Browse Source

display available actions on the configuration screen

Shun Miyazawa 3 years ago
parent
commit
3f2dfb5939

+ 25 - 2
packages/app/src/components/Admin/AuditLog/AuditLogSettings.tsx

@@ -1,18 +1,25 @@
-import React, { FC } from 'react';
+import React, { FC, useState } from 'react';
 
 import { useTranslation } from 'react-i18next';
+import { Collapse } from 'reactstrap';
 
+import { useSWRxSearchableActions } from '~/stores/activity';
 import { useActivityExpirationSeconds } from '~/stores/context';
 
 export const AuditLogSettings: FC = () => {
   const { t } = useTranslation();
 
+  const [isExpandActionList, setIsExpandActionList] = useState(false);
+
   const { data: activityExpirationSecondsData } = useActivityExpirationSeconds();
   const activityExpirationSeconds = activityExpirationSecondsData != null ? activityExpirationSecondsData : 2592000;
 
+  const { data: searchableActionsData } = useSWRxSearchableActions();
+  const searchableActions = searchableActionsData != null ? searchableActionsData : [];
+
   return (
     <>
-      <h4>{t('admin:audit_log_management.activity_expiration_date')}</h4>
+      <h4 className="mt-4">{t('admin:audit_log_management.activity_expiration_date')}</h4>
       <p className="form-text text-muted">
         {t('admin:audit_log_management.activity_expiration_date_explain')}
       </p>
@@ -27,6 +34,22 @@ export const AuditLogSettings: FC = () => {
           }}
         />
       </p>
+
+      <h4 className="mt-4">{t('admin:audit_log_management.available_action_list')}</h4>
+      <p className="form-text text-muted">{t('admin:audit_log_management.available_action_list_explain')}</p>
+      <p className="mt-1">
+        <button type="button" className="btn btn-link p-0" aria-expanded="false" onClick={() => setIsExpandActionList(!isExpandActionList)}>
+          <i className={`fa fa-fw fa-arrow-right ${isExpandActionList ? 'fa-rotate-90' : ''}`}></i>
+          { t('admin:audit_log_management.action_list') }
+        </button>
+      </p>
+      <Collapse isOpen={isExpandActionList}>
+        <ul className="list-group">
+          { searchableActions.map(action => (
+            <li className="list-group-item">{ action }</li>
+          )) }
+        </ul>
+      </Collapse>
     </>
   );
 };

+ 5 - 0
packages/app/src/server/routes/apiv3/activity.ts

@@ -102,5 +102,10 @@ module.exports = (crowi: Crowi): Router => {
     }
   });
 
+  router.get('/searchable-actions', accessTokenParser, loginRequiredStrictly, adminRequired, async(req: Request, res: ApiV3Response) => {
+    const searchableActions = crowi.activityService.getAvailableActions(false);
+    return res.apiv3({ searchableActions });
+  });
+
   return router;
 };

+ 8 - 1
packages/app/src/stores/activity.ts

@@ -2,7 +2,7 @@ import { SWRResponse } from 'swr';
 import useSWRImmutable from 'swr/immutable';
 
 import { apiv3Get } from '../client/util/apiv3-client';
-import { IActivityHasId, ISearchFilter } from '../interfaces/activity';
+import { IActivityHasId, ISearchFilter, SupportedActionType } from '../interfaces/activity';
 import { PaginateResult } from '../interfaces/mongoose-utils';
 
 export const useSWRxActivity = (limit?: number, offset?: number, searchFilter?: ISearchFilter): SWRResponse<PaginateResult<IActivityHasId>, Error> => {
@@ -13,3 +13,10 @@ export const useSWRxActivity = (limit?: number, offset?: number, searchFilter?:
       .then(result => result.data.paginationResult),
   );
 };
+
+export const useSWRxSearchableActions = (): SWRResponse<SupportedActionType[], Error> => {
+  return useSWRImmutable(
+    ['/activity/searchable-actions'],
+    endpoint => apiv3Get(endpoint).then(result => result.data.searchableActions),
+  );
+};