Shun Miyazawa 3 ani în urmă
părinte
comite
6183f92bfe

+ 78 - 48
packages/app/src/components/Admin/AuditLog/SelectQueryItemsDropdown.tsx

@@ -1,71 +1,101 @@
 import React, {
-  FC, useState, useCallback, useEffect,
+  FC, useState, useCallback,
 } from 'react';
 
 import { useTranslation } from 'react-i18next';
 
+import { SupportedTargetModelType, SupportedActionType } from '~/interfaces/activity';
 
-type Props = {
-  dropdownLabel: string
-  dropdownItemList: string[]
-  onCheckItem: (items: string[]) => void
+
+type DropdownProps = {
+  targetModelName: SupportedTargetModelType
+  actionNames: SupportedActionType[]
+  checkedItems: Map<SupportedActionType, boolean>
+  onCheckItem: (action: SupportedActionType) => void
 }
 
-export const SelectQueryItemsDropdown: FC<Props> = (props: Props) => {
-  const { t } = useTranslation();
+const Dropdown: FC<DropdownProps> = (props: DropdownProps) => {
 
-  const { dropdownLabel, dropdownItemList, onCheckItem } = props;
+  const {
+    targetModelName, actionNames, checkedItems, onCheckItem,
+  } = props;
 
-  const [checkedItems, setCheckedItems] = useState<string[]>(dropdownItemList);
+  const [checkedAllItems, setCheckedAllItems] = useState(true);
 
-  const handleChange = useCallback((checkedItem: string) => {
-    setCheckedItems(
-      checkedItems.includes(checkedItem)
-        ? checkedItems.filter(item => item !== checkedItem)
-        : [...checkedItems, checkedItem],
-    );
-  }, [checkedItems]);
+  const handleChange = useCallback((action: SupportedActionType) => {
+    onCheckItem(action);
+  }, [onCheckItem]);
 
-  useEffect(() => {
-    if (onCheckItem != null) {
-      onCheckItem(checkedItems);
-    }
-  }, [onCheckItem, checkedItems]);
+  return (
+    <>
+      <div className="dropdown-item">
+        <div className="form-group px-2 m-0">
+          <input
+            type="checkbox"
+            className="form-check-input"
+            checked={checkedAllItems}
+            onChange={() => setCheckedAllItems(!checkedAllItems)}
+          />
+          <label className="form-check-label">{targetModelName}</label>
+        </div>
+      </div>
+      {
+        actionNames.map(action => (
+          <div className="dropdown-item" key={action}>
+            <div className="form-group px-4 m-0">
+              <input
+                type="checkbox"
+                className="form-check-input"
+                id={`checkbox${action}`}
+                onChange={() => { handleChange(action) }}
+                checked={checkedItems.get(action)}
+              />
+              <label
+                className="form-check-label"
+                htmlFor={`checkbox${action}`}
+              >
+                {action}
+              </label>
+            </div>
+          </div>
+        ))
+      }
+    </>
+  );
+};
+
+
+type Props = {
+  dropdownItems: Array<{
+    targetModelName: SupportedTargetModelType
+    actionNames: SupportedActionType[]
+    checkedItems: Map<SupportedActionType, boolean>
+    onCheckItem: (action: SupportedActionType) => void
+  }>
+}
+
+export const SelectQueryItemsDropdown: FC<Props> = (props: Props) => {
+  const { t } = useTranslation();
+
+  const { dropdownItems } = props;
 
   return (
     <div className="btn-group mr-2 mb-3">
       <div className="dropdown">
         <button className="btn btn-outline-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown">
-          {t(`admin:audit_log_management.${dropdownLabel}`)}
+          {t('admin:audit_log_management.select_action')}
         </button>
         <ul className="dropdown-menu" aria-labelledby="dropdownMenuButton">
-          <div className="dropdown-item">
-            <div className="form-group px-2 m-0">
-              <input type="checkbox" className="form-check-input" />
-              <label className="form-check-label">Page</label>
+          {dropdownItems.map(item => (
+            <div key={item.targetModelName}>
+              <Dropdown
+                targetModelName={item.targetModelName}
+                actionNames={item.actionNames}
+                checkedItems={item.checkedItems}
+                onCheckItem={item.onCheckItem}
+              />
             </div>
-          </div>
-          {
-            dropdownItemList.map(item => (
-              <div className="dropdown-item" key={item}>
-                <div className="form-group px-4 m-0">
-                  <input
-                    type="checkbox"
-                    className="form-check-input"
-                    id={`checkbox${item}`}
-                    onChange={() => { handleChange(item) }}
-                    checked={checkedItems.includes(item)}
-                  />
-                  <label
-                    className="form-check-label"
-                    htmlFor={`checkbox${item}`}
-                  >
-                    {item}
-                  </label>
-                </div>
-              </div>
-            ))
-          }
+          ))}
         </ul>
       </div>
     </div>

+ 25 - 10
packages/app/src/components/Admin/AuditLogManagement.tsx

@@ -2,7 +2,9 @@ import React, { FC, useState, useCallback } from 'react';
 
 import { useTranslation } from 'react-i18next';
 
-import { AllSupportedActionType } from '~/interfaces/activity';
+import {
+  SUPPORTED_TARGET_MODEL_TYPE, SupportedActionType, AllSupportedPageAction, AllSupportedCommentAction, AllSupportedActionType,
+} from '~/interfaces/activity';
 import { useSWRxActivityList } from '~/stores/activity';
 
 import PaginationWrapper from '../PaginationWrapper';
@@ -21,13 +23,16 @@ export const AuditLogManagement: FC = () => {
    */
   const [activePage, setActivePage] = useState<number>(1);
   const offset = (activePage - 1) * PAGING_LIMIT;
-  const [actionNames, setActionNames] = useState<string[] | undefined>(undefined);
+
+  const [checkedItems, setCheckedItems] = useState(
+    new Map<SupportedActionType, boolean>(AllSupportedActionType.map(action => [action, true])),
+  );
 
   /*
    * Fetch
    */
   const query = {
-    action: actionNames,
+    action: ['PAGE_LIKE'],
   };
   const { data: activityListData, error } = useSWRxActivityList(PAGING_LIMIT, offset, query);
   const activityList = activityListData?.docs != null ? activityListData.docs : [];
@@ -41,19 +46,29 @@ export const AuditLogManagement: FC = () => {
     setActivePage(selectedPageNum);
   }, []);
 
-  const checkActionNameHandler = useCallback((checkedItems: string[]) => {
-    setActivePage(1);
-    setActionNames(checkedItems.length === 0 ? undefined : checkedItems);
-  }, []);
+  const checkActionNameHandler = useCallback((action: SupportedActionType) => {
+    setCheckedItems(new Map(checkedItems.set(action, !checkedItems.get(action))));
+  }, [checkedItems, setCheckedItems]);
 
   return (
     <div data-testid="admin-auditlog">
       <h2>{t('AuditLog')}</h2>
 
       <SelectQueryItemsDropdown
-        dropdownLabel="select_action"
-        dropdownItemList={AllSupportedActionType}
-        onCheckItem={checkActionNameHandler}
+        dropdownItems={[
+          {
+            targetModelName: SUPPORTED_TARGET_MODEL_TYPE.MODEL_PAGE,
+            actionNames: AllSupportedPageAction,
+            checkedItems,
+            onCheckItem: checkActionNameHandler,
+          },
+          {
+            targetModelName: SUPPORTED_TARGET_MODEL_TYPE.MODEL_COMMENT,
+            actionNames: AllSupportedCommentAction,
+            checkedItems,
+            onCheckItem: checkActionNameHandler,
+          },
+        ]}
       />
 
       { isLoading

+ 22 - 4
packages/app/src/interfaces/activity.ts

@@ -21,6 +21,7 @@ const ACTION_COMMENT_UPDATE = 'COMMENT_UPDATE';
 
 export const SUPPORTED_TARGET_MODEL_TYPE = {
   MODEL_PAGE,
+  MODEL_COMMENT,
 } as const;
 
 export const SUPPORTED_EVENT_MODEL_TYPE = {
@@ -46,15 +47,32 @@ export const AllSupportedTargetModelType = Object.values(SUPPORTED_TARGET_MODEL_
 export const AllSupportedEventModelType = Object.values(SUPPORTED_EVENT_MODEL_TYPE);
 export const AllSupportedActionType = Object.values(SUPPORTED_ACTION_TYPE);
 
-type supportedTargetModelType = typeof SUPPORTED_TARGET_MODEL_TYPE[keyof typeof SUPPORTED_TARGET_MODEL_TYPE];
+export const AllSupportedPageAction = Object.values({
+  ACTION_PAGE_LIKE,
+  ACTION_PAGE_BOOKMARK,
+  ACTION_PAGE_CREATE,
+  ACTION_PAGE_UPDATE,
+  ACTION_PAGE_RENAME,
+  ACTION_PAGE_DUPLICATE,
+  ACTION_PAGE_DELETE,
+  ACTION_PAGE_DELETE_COMPLETELY,
+  ACTION_PAGE_REVERT,
+} as const);
+
+export const AllSupportedCommentAction = Object.values({
+  ACTION_COMMENT_CREATE,
+  ACTION_COMMENT_UPDATE,
+} as const);
+
+export type SupportedTargetModelType = typeof SUPPORTED_TARGET_MODEL_TYPE[keyof typeof SUPPORTED_TARGET_MODEL_TYPE];
 // type supportedEventModelType = typeof SUPPORTED_EVENT_MODEL_TYPE[keyof typeof SUPPORTED_EVENT_MODEL_TYPE];
-type supportedActionType = typeof SUPPORTED_ACTION_TYPE[keyof typeof SUPPORTED_ACTION_TYPE];
+export type SupportedActionType = typeof SUPPORTED_ACTION_TYPE[keyof typeof SUPPORTED_ACTION_TYPE];
 
 export type IActivity = {
   user?: IUser
-  targetModel: supportedTargetModelType
+  targetModel: SupportedTargetModelType
   targe: string
-  action: supportedActionType
+  action: SupportedActionType
   createdAt: Date
 }