willbarrett commented on a change in pull request #10680:
URL: 
https://github.com/apache/incubator-superset/pull/10680#discussion_r477609862



##########
File path: superset-frontend/src/views/CRUD/chart/ChartList.tsx
##########
@@ -102,190 +80,239 @@ const createFetchDatasets = (handleError: (err: 
Response) => void) => async (
   }
   return [];
 };
-class ChartList extends React.PureComponent<Props, State> {
-  static propTypes = {
-    addDangerToast: PropTypes.func.isRequired,
-  };
 
-  state: State = {
-    bulkSelectEnabled: false,
-    chartCount: 0,
-    charts: [],
-    favoriteStatus: {}, // Hash mapping dashboard id to 'isStarred' status
-    lastFetchDataConfig: null,
-    loading: true,
-    permissions: [],
-    sliceCurrentlyEditing: null,
-  };
+interface ChartListProps {
+  addDangerToast: (msg: string) => void;
+  addSuccessToast: (msg: string) => void;
+}
+
+function ChartList(props: ChartListProps) {
+  const {
+    state: {
+      loading,
+      resourceCount: chartCount,
+      resourceCollection: charts,
+      bulkSelectEnabled,
+    },
+    setResourceCollection: setCharts,
+    hasPerm,
+    fetchData,
+    toggleBulkSelect,
+    refreshData,
+  } = useListViewResource<Chart>('chart', t('chart'), props.addDangerToast);
+  const [favoriteStatusRef, fetchFaveStar, saveFaveStar] = useFavoriteStatus(
+    {},
+    FAVESTAR_BASE_URL,
+    props.addDangerToast,
+  );
+  const [
+    sliceCurrentlyEditing,
+    setSliceCurrentlyEditing,
+  ] = useState<Slice | null>(null);
+
+  const canEdit = hasPerm('can_edit');
+  const canDelete = hasPerm('can_delete');
+  const initialSort = [{ id: 'changed_on_delta_humanized', desc: true }];
+
+  function openChartEditModal(chart: Chart) {
+    setSliceCurrentlyEditing({
+      slice_id: chart.id,
+      slice_name: chart.slice_name,
+      description: chart.description,
+      cache_timeout: chart.cache_timeout,
+    });
+  }
+
+  function closeChartEditModal() {
+    setSliceCurrentlyEditing(null);
+  }
+
+  function handleChartUpdated(edits: Chart) {
+    // update the chart in our state with the edited info
+    const newCharts = charts.map(chart =>
+      chart.id === edits.id ? { ...chart, ...edits } : chart,
+    );
+    setCharts(newCharts);
+  }
+
+  function handleChartDelete({ id, slice_name: sliceName }: Chart) {
+    SupersetClient.delete({
+      endpoint: `/api/v1/chart/${id}`,
+    }).then(
+      () => {
+        refreshData();
+        props.addSuccessToast(t('Deleted: %s', sliceName));
+      },
+      () => {
+        props.addDangerToast(t('There was an issue deleting: %s', sliceName));
+      },
+    );
+  }
 
-  componentDidMount() {
-    SupersetClient.get({
-      endpoint: `/api/v1/chart/_info`,
+  function handleBulkChartDelete(chartsToDelete: Chart[]) {
+    SupersetClient.delete({
+      endpoint: `/api/v1/chart/?q=${rison.encode(
+        chartsToDelete.map(({ id }) => id),
+      )}`,
     }).then(
-      ({ json: infoJson = {} }) => {
-        this.setState({
-          permissions: infoJson.permissions,
-        });
+      ({ json = {} }) => {
+        refreshData();
+        props.addSuccessToast(json.message);
       },
       createErrorHandler(errMsg =>
-        this.props.addDangerToast(
-          t('An error occurred while fetching chart info: %s', errMsg),
+        props.addDangerToast(
+          t('There was an issue deleting the selected charts: %s', errMsg),
         ),
       ),
     );
   }
 
-  get canEdit() {
-    return this.hasPerm('can_edit');
-  }
-
-  get canDelete() {
-    return this.hasPerm('can_delete');
+  function renderFaveStar(id: number) {
+    return (
+      <FaveStar
+        itemId={id}
+        fetchFaveStar={fetchFaveStar}
+        saveFaveStar={saveFaveStar}
+        isStarred={!!favoriteStatusRef.current[id]}
+        height={20}
+        width={20}
+      />
+    );
   }
 
-  initialSort = [{ id: 'changed_on_delta_humanized', desc: true }];
-
-  fetchMethods = createFaveStarHandlers(
-    FAVESTAR_BASE_URL,
-    this,
-    (message: string) => {
-      this.props.addDangerToast(message);
-    },
-  );
-
-  columns = [
-    {
-      Cell: ({ row: { original } }: any) => {
-        return (
-          <FaveStar
-            itemId={original.id}
-            fetchFaveStar={this.fetchMethods.fetchFaveStar}
-            saveFaveStar={this.fetchMethods.saveFaveStar}
-            isStarred={!!this.state.favoriteStatus[original.id]}
-            height={20}
-          />
-        );
+  const columns = useMemo(
+    () => [
+      {
+        Cell: ({
+          row: {
+            original: { id },
+          },
+        }: any) => renderFaveStar(id),
+        Header: '',
+        id: 'favorite',
+        disableSortBy: true,
       },
-      Header: '',
-      id: 'favorite',
-      disableSortBy: true,
-    },
-    {
-      Cell: ({
-        row: {
-          original: { url, slice_name: sliceName },
-        },
-      }: any) => <a href={url}>{sliceName}</a>,
-      Header: t('Chart'),
-      accessor: 'slice_name',
-    },
-    {
-      Cell: ({
-        row: {
-          original: { viz_type: vizType },
-        },
-      }: any) => vizType,
-      Header: t('Visualization Type'),
-      accessor: 'viz_type',
-    },
-    {
-      Cell: ({
-        row: {
-          original: { datasource_name_text: dsNameTxt, datasource_url: dsUrl },
-        },
-      }: any) => <a href={dsUrl}>{dsNameTxt}</a>,
-      Header: t('Datasource'),
-      accessor: 'datasource_name',
-    },
-    {
-      Cell: ({
-        row: {
-          original: {
-            changed_by_name: changedByName,
-            changed_by_url: changedByUrl,
+      {
+        Cell: ({
+          row: {
+            original: { url, slice_name: sliceName },
           },
-        },
-      }: any) => <a href={changedByUrl}>{changedByName}</a>,
-      Header: t('Modified By'),
-      accessor: 'changed_by.first_name',
-    },
-    {
-      Cell: ({
-        row: {
-          original: { changed_on_delta_humanized: changedOn },
-        },
-      }: any) => <span className="no-wrap">{changedOn}</span>,
-      Header: t('Last Modified'),
-      accessor: 'changed_on_delta_humanized',
-    },
-    {
-      accessor: 'description',
-      hidden: true,
-      disableSortBy: true,
-    },
-    {
-      accessor: 'owners',
-      hidden: true,
-      disableSortBy: true,
-    },
-    {
-      accessor: 'datasource_id',
-      hidden: true,
-      disableSortBy: true,
-    },
-    {
-      Cell: ({ row: { original } }: any) => {
-        const handleDelete = () => this.handleChartDelete(original);
-        const openEditModal = () => this.openChartEditModal(original);
-        if (!this.canEdit && !this.canDelete) {
-          return null;
-        }
+        }: any) => <a href={url}>{sliceName}</a>,
+        Header: t('Chart'),
+        accessor: 'slice_name',
+      },
+      {
+        Cell: ({
+          row: {
+            original: { viz_type: vizType },
+          },
+        }: any) => vizType,
+        Header: t('Visualization Type'),
+        accessor: 'viz_type',
+      },
+      {
+        Cell: ({
+          row: {
+            original: {
+              datasource_name_text: dsNameTxt,
+              datasource_url: dsUrl,
+            },
+          },
+        }: any) => <a href={dsUrl}>{dsNameTxt}</a>,
+        Header: t('Datasource'),
+        accessor: 'datasource_name',
+      },
+      {
+        Cell: ({
+          row: {
+            original: {
+              changed_by_name: changedByName,
+              changed_by_url: changedByUrl,
+            },
+          },
+        }: any) => <a href={changedByUrl}>{changedByName}</a>,
+        Header: t('Modified By'),
+        accessor: 'changed_by.first_name',
+      },
+      {
+        Cell: ({
+          row: {
+            original: { changed_on_delta_humanized: changedOn },
+          },
+        }: any) => <span className="no-wrap">{changedOn}</span>,
+        Header: t('Last Modified'),
+        accessor: 'changed_on_delta_humanized',
+      },
+      {
+        accessor: 'description',
+        hidden: true,
+        disableSortBy: true,

Review comment:
       Understood. Please don't burn too many cycles on it given that it maps 
onto a 3rd party library's naming. Just a passing thought.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to