Ver Fonte

Merge pull request #27 from weseek/support/plugincards

support: plugincards
ryoji-s há 3 anos atrás
pai
commit
18f98ea1a7

+ 3 - 3
packages/app/src/components/Admin/Common/AdminNavigation.jsx

@@ -38,7 +38,7 @@ const AdminNavigation = (props) => {
         { t('full_text_search_management.full_text_search_management') }</>;
         { t('full_text_search_management.full_text_search_management') }</>;
       // TODO: Consider where to place the "AuditLog"
       // TODO: Consider where to place the "AuditLog"
       case 'audit-log':                return <><i className="icon-fw icon-feed"></i>            { t('audit_log_management.audit_log')}</>;
       case 'audit-log':                return <><i className="icon-fw icon-feed"></i>            { t('audit_log_management.audit_log')}</>;
-      case 'plugins-extention':        return <><i className="icon-fw fa fa-plug"></i>           Plugins Extention </>;
+      case 'plugins-extension':        return <><i className="icon-fw fa fa-plug"></i>           Plugins Extension </>;
       case 'cloud':                    return <><i className="icon-fw icon-share-alt"></i>       { t('to_cloud_settings')} </>;
       case 'cloud':                    return <><i className="icon-fw icon-share-alt"></i>       { t('to_cloud_settings')} </>;
       default:                         return <><i className="icon-fw icon-home"></i>            { t('wiki_management_home_page') }</>;
       default:                         return <><i className="icon-fw icon-home"></i>            { t('wiki_management_home_page') }</>;
       /* eslint-enable no-multi-spaces */
       /* eslint-enable no-multi-spaces */
@@ -95,7 +95,7 @@ const AdminNavigation = (props) => {
         <MenuLink menu="user-groups"  isListGroupItems isActive={isActiveMenu('/user-groups')} />
         <MenuLink menu="user-groups"  isListGroupItems isActive={isActiveMenu('/user-groups')} />
         <MenuLink menu="search"       isListGroupItems isActive={isActiveMenu('/search')} />
         <MenuLink menu="search"       isListGroupItems isActive={isActiveMenu('/search')} />
         <MenuLink menu="audit-log"    isListGroupItems isActive={isActiveMenu('/audit-log')} />
         <MenuLink menu="audit-log"    isListGroupItems isActive={isActiveMenu('/audit-log')} />
-        <MenuLink menu="plugins-extention"    isListGroupItems isActive={isActiveMenu('/plugins-extention')} />
+        <MenuLink menu="plugins-extension"    isListGroupItems isActive={isActiveMenu('/plugins-extension')} />
         {/* {growiCloudUri != null && growiAppIdForGrowiCloud != null
         {/* {growiCloudUri != null && growiAppIdForGrowiCloud != null
           && (
           && (
             <a
             <a
@@ -144,7 +144,7 @@ const AdminNavigation = (props) => {
             {isActiveMenu('/user-groups') &&       <MenuLabel menu="user-groups" />}
             {isActiveMenu('/user-groups') &&       <MenuLabel menu="user-groups" />}
             {isActiveMenu('/search') &&            <MenuLabel menu="search" />}
             {isActiveMenu('/search') &&            <MenuLabel menu="search" />}
             {isActiveMenu('/audit-log') &&         <MenuLabel menu="audit-log" />}
             {isActiveMenu('/audit-log') &&         <MenuLabel menu="audit-log" />}
-            {isActiveMenu('/plugins-extention') && <MenuLabel menu="plugins-extention" />}
+            {isActiveMenu('/plugins-extension') && <MenuLabel menu="plugins-extension" />}
             {/* eslint-enable no-multi-spaces */}
             {/* eslint-enable no-multi-spaces */}
           </span>
           </span>
         </button>
         </button>

+ 1 - 1
packages/app/src/components/Admin/PluginsExtension/PluginInstallerForm.tsx

@@ -22,7 +22,7 @@ export const PluginInstallerForm = (): JSX.Element => {
     };
     };
 
 
     try {
     try {
-      await apiv3Post('/plugins-extention', { pluginInstallerForm });
+      await apiv3Post('/plugins-extension', { pluginInstallerForm });
       toastSuccess('Plugin Install Successed!');
       toastSuccess('Plugin Install Successed!');
     }
     }
     catch (err) {
     catch (err) {

+ 26 - 6
packages/app/src/components/Admin/PluginsExtension/PluginsExtensionPageContents.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import React from 'react';
 
 
-import { usePluginEntries } from '~/stores/context';
+import { useSWRxPlugins } from '~/stores/plugin-test';
 
 
 import Loading from './Loading';
 import Loading from './Loading';
 import { PluginCard } from './PluginCard';
 import { PluginCard } from './PluginCard';
@@ -8,10 +8,30 @@ import { PluginInstallerForm } from './PluginInstallerForm';
 // TODO: i18n
 // TODO: i18n
 
 
 export const PluginsExtensionPageContents = (): JSX.Element => {
 export const PluginsExtensionPageContents = (): JSX.Element => {
-  const { data, mutate } = usePluginEntries();
+  const { data, mutate } = useSWRxPlugins();
 
 
-  if (data == null) {
-    return <Loading />;
+  if (data?.data?.plugins == null) {
+    return (
+      <>
+        <div className="row mb-5">
+          <div className="col-lg-12">
+            <h2 className="admin-setting-header">Plugin Installer</h2>
+            <PluginInstallerForm />
+          </div>
+        </div>
+        <div className="row mb-5">
+          <div className="col-lg-12">
+            <h2 className="admin-setting-header">Plugins
+              <button type="button" className="btn btn-sm ml-auto grw-btn-reload" onClick={() => mutate()}>
+                <i className="icon icon-reload"></i>
+              </button>
+            </h2>
+            <Loading />
+          </div>
+        </div>
+      </>
+
+    );
   }
   }
 
 
   return (
   return (
@@ -32,11 +52,11 @@ export const PluginsExtensionPageContents = (): JSX.Element => {
             </button>
             </button>
           </h2>
           </h2>
           <div className="d-grid gap-5">
           <div className="d-grid gap-5">
-            { data.map((item) => {
+            { data?.data?.plugins.map((item) => {
               const pluginName = item[0].meta.name;
               const pluginName = item[0].meta.name;
               const pluginUrl = item[0].origin.url;
               const pluginUrl = item[0].origin.url;
               const pluginDiscription = item[0].meta.desc;
               const pluginDiscription = item[0].meta.desc;
-              return <PluginCard key={pluginName} name={pluginName} url={pluginUrl} description={pluginDiscription} />;
+              return <PluginCard key={item[0]._id} name={pluginName} url={pluginUrl} description={pluginDiscription} />;
             })}
             })}
           </div>
           </div>
         </div>
         </div>

+ 3 - 4
packages/app/src/pages/admin/[[...path]].page.tsx

@@ -36,7 +36,7 @@ import { GrowiPlugin } from '~/interfaces/plugin';
 import ConfigLoader from '~/server/service/config-loader';
 import ConfigLoader from '~/server/service/config-loader';
 import {
 import {
   useCurrentUser, /* useSearchServiceConfigured, */ useIsAclEnabled, useIsMailerSetup, useIsSearchServiceReachable, useSiteUrl,
   useCurrentUser, /* useSearchServiceConfigured, */ useIsAclEnabled, useIsMailerSetup, useIsSearchServiceReachable, useSiteUrl,
-  useAuditLogEnabled, useAuditLogAvailableActions, usePluginEntries,
+  useAuditLogEnabled, useAuditLogAvailableActions,
 } from '~/stores/context';
 } from '~/stores/context';
 import { useIsMaintenanceMode } from '~/stores/maintenanceMode';
 import { useIsMaintenanceMode } from '~/stores/maintenanceMode';
 
 
@@ -185,8 +185,8 @@ const AdminMarkdownSettingsPage: NextPage<Props> = (props: Props) => {
       title: t('audit_log_management.audit_log'),
       title: t('audit_log_management.audit_log'),
       component: <AuditLogManagement />,
       component: <AuditLogManagement />,
     },
     },
-    'plugins-extention': {
-      title: 'Plugins Extention',
+    'plugins-extension': {
+      title: 'Plugins Extension',
       component: <PluginsExtensionPageContents />,
       component: <PluginsExtensionPageContents />,
     },
     },
   };
   };
@@ -213,7 +213,6 @@ const AdminMarkdownSettingsPage: NextPage<Props> = (props: Props) => {
 
 
   useAuditLogEnabled(props.auditLogEnabled);
   useAuditLogEnabled(props.auditLogEnabled);
   useAuditLogAvailableActions(props.auditLogAvailableActions);
   useAuditLogAvailableActions(props.auditLogAvailableActions);
-  usePluginEntries(props.pluginManifestEntries);
 
 
   const injectableContainers: Container<any>[] = [];
   const injectableContainers: Container<any>[] = [];
 
 

+ 1 - 1
packages/app/src/server/routes/apiv3/index.js

@@ -99,7 +99,7 @@ module.exports = (crowi, app, isInstalled) => {
     userActivation.validateCompleteRegistration,
     userActivation.validateCompleteRegistration,
     userActivation.completeRegistrationAction(crowi));
     userActivation.completeRegistrationAction(crowi));
 
 
-  router.use('/plugins-extention', require('./plugins-extention')(crowi));
+  router.use('/plugins-extension', require('./plugins-extension')(crowi));
 
 
   router.use('/user-ui-settings', require('./user-ui-settings')(crowi));
   router.use('/user-ui-settings', require('./user-ui-settings')(crowi));
 
 

+ 13 - 15
packages/app/src/server/routes/apiv3/plugins-extention.ts → packages/app/src/server/routes/apiv3/plugins-extension.ts

@@ -1,5 +1,4 @@
 import express, { Request } from 'express';
 import express, { Request } from 'express';
-import { PromiseProvider } from 'mongoose';
 
 
 import Crowi from '../../crowi';
 import Crowi from '../../crowi';
 
 
@@ -11,20 +10,19 @@ module.exports = (crowi: Crowi) => {
   const router = express.Router();
   const router = express.Router();
   const { pluginService } = crowi;
   const { pluginService } = crowi;
 
 
-  // router.get('/', async(req, res) => {
-  //   if (pluginService == null) {
-  //     // return res.apiv3Err(400);
-  //     return; // console.log('err');
-  //   }
-
-  //   try {
-  //     const res = await pluginService.getPlugins();
-  //     return res.apiv3(res);
-  //   }
-  //   catch (err) {
-  //     // return res.apiv3Err(err, 400);
-  //   }
-  // });
+  router.get('/', async(req: any, res: any) => {
+    if (pluginService == null) {
+      return res.apiv3Err(400);
+    }
+
+    try {
+      const data = await pluginService.getPlugins();
+      return res.apiv3({ plugins: data });
+    }
+    catch (err) {
+      return res.apiv3Err(err, 400);
+    }
+  });
 
 
   router.post('/', async(req: PluginInstallerFormRequest, res: ApiV3Response) => {
   router.post('/', async(req: PluginInstallerFormRequest, res: ApiV3Response) => {
     if (pluginService == null) {
     if (pluginService == null) {

+ 0 - 2
packages/app/src/server/service/plugin.ts

@@ -87,8 +87,6 @@ export class PluginService {
   }
   }
 
 
   async getPlugins(): Promise<any> {
   async getPlugins(): Promise<any> {
-    // const initialProps: DocumentInitialProps = await Document.getInitialProps(ctx);
-
     const GrowiPlugin = mongoose.model<GrowiPlugin>('GrowiPlugin');
     const GrowiPlugin = mongoose.model<GrowiPlugin>('GrowiPlugin');
     const growiPlugins = await GrowiPlugin.find({ isEnabled: true });
     const growiPlugins = await GrowiPlugin.find({ isEnabled: true });
     const pluginManifestEntries: GrowiPluginManifestEntries = await ActivatePluginService.retrievePluginManifests(growiPlugins);
     const pluginManifestEntries: GrowiPluginManifestEntries = await ActivatePluginService.retrievePluginManifests(growiPlugins);

+ 0 - 4
packages/app/src/stores/context.tsx

@@ -178,10 +178,6 @@ export const useIsMailerSetup = (initialData?: boolean): SWRResponse<boolean, an
   return useStaticSWR('isMailerSetup', initialData);
   return useStaticSWR('isMailerSetup', initialData);
 };
 };
 
 
-export const usePluginEntries = (initialData?: any): SWRResponse<any, any> => {
-  return useStaticSWR('pluginEntries', initialData);
-};
-
 export const useIsSearchScopeChildrenAsDefault = (initialData?: boolean) : SWRResponse<boolean, Error> => {
 export const useIsSearchScopeChildrenAsDefault = (initialData?: boolean) : SWRResponse<boolean, Error> => {
   return useStaticSWR<boolean, Error>('isSearchScopeChildrenAsDefault', initialData);
   return useStaticSWR<boolean, Error>('isSearchScopeChildrenAsDefault', initialData);
 };
 };

+ 12 - 6
packages/app/src/stores/plugin-test.tsx

@@ -12,17 +12,23 @@ import { IResAttachmentList } from '~/interfaces/attachment';
 
 
 import { PluginResult } from '../models/SearchResult';
 import { PluginResult } from '../models/SearchResult';
 
 
-
+// TODO: Correct types
 const pluginsFetcher = () => {
 const pluginsFetcher = () => {
   return async() => {
   return async() => {
-    const reqUrl = '/plugins-extention';
-    const data = await fetch(reqUrl).then(res => res.json());
-    return data.searchResult;
+    const reqUrl = '/plugins-extension';
+    try {
+      const data = await apiv3Get(reqUrl);
+      return data;
+    }
+    catch (err) {
+      // TODO: Error handling
+      console.log('err', err);
+    }
   };
   };
 };
 };
 
 
-export const useSWRxPlugins = (): SWRResponse<PluginResult | null, Error> => {
-  return useSWR('/extention', pluginsFetcher());
+export const useSWRxPlugins = (): SWRResponse<any | null, Error> => {
+  return useSWR('/extension', pluginsFetcher());
 };
 };