From 93f22eca51299fa364ded160758b08564d5ec5e4 Mon Sep 17 00:00:00 2001
From: chenos <chenlinxh@gmail.com>
Date: Fri, 22 Jan 2021 10:10:46 +0800
Subject: [PATCH] =?UTF-8?q?=E5=B0=8F=E7=BB=86=E8=8A=82=E8=A1=A5=E5=85=85?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../components/views/SortableTable/index.tsx  | 31 +++++++-
 packages/app/src/components/views/Table.tsx   |  2 +-
 .../plugin-pages/src/actions/roles.pages.ts   | 79 +++++++++++++++++++
 .../src/actions/roles.collections.ts          | 20 ++++-
 4 files changed, 128 insertions(+), 4 deletions(-)

diff --git a/packages/app/src/components/views/SortableTable/index.tsx b/packages/app/src/components/views/SortableTable/index.tsx
index 477efa26..4aa4dffd 100644
--- a/packages/app/src/components/views/SortableTable/index.tsx
+++ b/packages/app/src/components/views/SortableTable/index.tsx
@@ -8,6 +8,8 @@ import get from 'lodash/get';
 import './style.less';
 import Field from '../Field';
 import cloneDeep from 'lodash/cloneDeep';
+import { Checkbox, message } from 'antd';
+import api from '@/api-client';
 
 export const SortableItem = sortableElement(props => <tr {...props} />);
 export const SortableContainer = sortableContainer(props => <tbody {...props} />);
@@ -58,11 +60,38 @@ export const components = ({data = {}, rowKey, mutate, onMoved, isFieldComponent
   };
 };
 
-export function fields2columns(fields) {
+export function fields2columns(fields, ctx: any = {}) {
   const columns: any[] = fields.map(item => {
     const field = cloneDeep(item);
     field.render = (value, record) => field.interface === 'sort' ? <DragHandle/> : <Field data={record} viewType={'table'} schema={field} value={value}/>;
     field.className = `${field.className||''} noco-field-${field.interface}`;
+    if (field.editable && field.interface === 'boolean') {
+      field.title = (
+        <span>
+          <Checkbox onChange={async (e) => {
+            try {
+              await api.resource(field.resource).update({
+                associatedKey: ctx.associatedKey,
+                // resourceKey: data.id,
+                // tableName: data.tableName||'pages',
+                values: {
+                  accessible: e.target.checked,
+                },
+              });
+              message.success('淇濆瓨鎴愬姛');
+              if (ctx.refresh) {
+                ctx.refresh();
+              }
+            } catch (error) {
+              message.error('淇濆瓨澶辫触');
+            }
+            
+          }}/>
+          {' '}
+          {field.title}
+        </span>
+      );
+    }
     return {
       ...field,
       ...(field.component||{}),
diff --git a/packages/app/src/components/views/Table.tsx b/packages/app/src/components/views/Table.tsx
index b6895f0d..1a3cab4b 100644
--- a/packages/app/src/components/views/Table.tsx
+++ b/packages/app/src/components/views/Table.tsx
@@ -154,7 +154,7 @@ export function Table(props: TableProps) {
           indicator: icon,
           // className: 'spinning--absolute m32',
         }}
-        columns={fields2columns(fields)}
+        columns={fields2columns(fields, {associatedKey, refresh})}
         dataSource={data?.list||(data as any)}
         onChange={(pagination, filters, sorter, extra) => {
           run({...params[0], sorter});
diff --git a/packages/plugin-pages/src/actions/roles.pages.ts b/packages/plugin-pages/src/actions/roles.pages.ts
index 53392a38..84c3486b 100644
--- a/packages/plugin-pages/src/actions/roles.pages.ts
+++ b/packages/plugin-pages/src/actions/roles.pages.ts
@@ -3,6 +3,69 @@ import Database from '@nocobase/database';
 import { flatToTree } from '../utils';
 import { Op } from 'sequelize';
 
+async function getRoutes(ctx) {
+  const database: Database = ctx.db;
+  const Page = database.getModel('pages');
+  const Collection = database.getModel('collections');
+  let pages = await Page.findAll(Page.parseApiJson(ctx.state.developerMode ? {
+    filter: {
+      'parent_id.$notNull': true,
+    },
+    sort: ['sort'],
+  } : {
+    filter: {
+      'parent_id.$notNull': true,
+      developerMode: {'$isFalsy': true},
+    },
+    sort: ['sort'],
+  }));
+  const items = [];
+  for (const page of pages) {
+    items.push({
+      routable_type: 'pages',
+      routable_id: page.id,
+    });
+    if (page.get('path') === '/collections') {
+      const collections = await Collection.findAll(Collection.parseApiJson(ctx.state.developerMode ? {
+        filter: {
+          showInDataMenu: true,
+        },
+        sort: ['sort'],
+      }: {
+        filter: {
+          developerMode: {'$isFalsy': true},
+          showInDataMenu: true,
+        },
+        sort: ['sort'],
+      }));
+      for (const collection of collections) {
+        items.push({
+          routable_type: 'collections',
+          routable_id: collection.id,
+        });
+        const views = await collection.getViews({
+          where: {
+            [Op.or]: [
+              { showInDataMenu: true },
+              { default: true }
+            ]
+          },
+          order: [['sort', 'asc']]
+        });
+        if (views.length > 1) {
+          for (const view of views) {
+            items.push({
+              routable_id: view.id,
+              routable_type: 'views',
+            });
+          }
+        }
+      }
+    }
+  }
+  return items;
+}
+
 export async function list(ctx: actions.Context, next: actions.Next) {
   const database: Database = ctx.db;
   const { associatedKey, associated } = ctx.action.params;
@@ -125,6 +188,22 @@ export async function update(ctx: actions.Context, next: actions.Next) {
     }
   } = ctx.action.params;
 
+  if (!resourceKey) {
+    if (accessible === false) {
+      await associated.updateAssociations({
+        routes: [],
+      });
+    } else if (accessible === true) {
+      const routes = await getRoutes(ctx);
+      // console.log(routes);
+      await associated.updateAssociations({
+        routes,
+      });
+    }
+    ctx.body = {};
+    return next();
+  }
+
   console.log(ctx.action.params, { routable_type: tableName, routable_id: resourceKey });
   let [route] = await associated.getRoutes({
     where: { routable_type: tableName, routable_id: resourceKey },
diff --git a/packages/plugin-permissions/src/actions/roles.collections.ts b/packages/plugin-permissions/src/actions/roles.collections.ts
index cfe45e93..053535a6 100644
--- a/packages/plugin-permissions/src/actions/roles.collections.ts
+++ b/packages/plugin-permissions/src/actions/roles.collections.ts
@@ -1,5 +1,6 @@
 import { Op } from 'sequelize';
 import { actions } from '@nocobase/actions';
+import _ from 'lodash';
 
 export async function list(ctx: actions.Context, next: actions.Next) {
   const { associated } = ctx.action.params;
@@ -16,8 +17,8 @@ export async function list(ctx: actions.Context, next: actions.Next) {
         item.set('permissions', [permission]); // 杈撳嚭
       }
     });
-    next();
   });
+  await next();
 }
 
 export async function get(ctx: actions.Context, next: actions.Next) {
@@ -26,7 +27,22 @@ export async function get(ctx: actions.Context, next: actions.Next) {
     associated
   } = ctx.action.params;
 
-  ctx.body = await ctx.ac.as(associated).can(resourceKey).permissions();
+  const permissions = await ctx.ac.as(associated).can(resourceKey).permissions();
+
+  const permission = await associated.getPermissions({
+    where: {
+      collection_name: resourceKey,
+    },
+    plain: true,
+    limit: 1,
+  });
+
+  console.log(permission);
+
+  ctx.body = {
+    ...permissions,
+    description: _.get(permission, 'description'),
+  };
 
   await next();
 }
-- 
GitLab