mirror of
				https://github.com/gristlabs/grist-core.git
				synced 2025-06-13 20:53:59 +00:00 
			
		
		
		
	(core) Duplicate page should copy filters.
Summary: Duplicate page also copies filters for all sections. Test Plan: nbrowser tests Reviewers: cyprien, alexmojaki Reviewed By: cyprien, alexmojaki Subscribers: alexmojaki Differential Revision: https://phab.getgrist.com/D3203
This commit is contained in:
		
							parent
							
								
									52d3f63203
								
							
						
					
					
						commit
						50821f655d
					
				@ -26,7 +26,7 @@ import {
 | 
			
		||||
  summarizePermissionSet
 | 
			
		||||
} from 'app/common/ACLPermissions';
 | 
			
		||||
import {ACLRuleCollection, SPECIAL_RULES_TABLE_ID} from 'app/common/ACLRuleCollection';
 | 
			
		||||
import {BulkColValues, RowRecord, UserAction} from 'app/common/DocActions';
 | 
			
		||||
import {BulkColValues, getColValues, RowRecord, UserAction} from 'app/common/DocActions';
 | 
			
		||||
import {
 | 
			
		||||
  FormulaProperties,
 | 
			
		||||
  getFormulaProperties,
 | 
			
		||||
@ -1371,26 +1371,6 @@ function syncRecords(tableData: TableData, newRecords: RowRecord[],
 | 
			
		||||
  return {userActions, rowIdMap};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert a list of rows into an object with columns of values, used for
 | 
			
		||||
 * BulkAddRecord/BulkUpdateRecord actions.
 | 
			
		||||
 */
 | 
			
		||||
function getColValues(records: RowRecord[]): BulkColValues {
 | 
			
		||||
  const colIdSet = new Set<string>();
 | 
			
		||||
  for (const r of records) {
 | 
			
		||||
    for (const c of Object.keys(r)) {
 | 
			
		||||
      if (c !== 'id') {
 | 
			
		||||
        colIdSet.add(c);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  const result: BulkColValues = {};
 | 
			
		||||
  for (const colId of colIdSet) {
 | 
			
		||||
    result[colId] = records.map(r => r[colId]);
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert a list of [before, after] rows into an object of changes, skipping columns which
 | 
			
		||||
 * haven't changed.
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import { ViewFieldRec, ViewSectionRec } from 'app/client/models/DocModel';
 | 
			
		||||
import { cssField, cssInput, cssLabel} from 'app/client/ui/MakeCopyMenu';
 | 
			
		||||
import { IPageWidget, toPageWidget } from 'app/client/ui/PageWidgetPicker';
 | 
			
		||||
import { confirmModal } from 'app/client/ui2018/modals';
 | 
			
		||||
import { BulkColValues, RowRecord, UserAction } from 'app/common/DocActions';
 | 
			
		||||
import { BulkColValues, getColValues, RowRecord, UserAction } from 'app/common/DocActions';
 | 
			
		||||
import { arrayRepeat } from 'app/common/gutil';
 | 
			
		||||
import { schema } from 'app/common/schema';
 | 
			
		||||
import { dom } from 'grainjs';
 | 
			
		||||
@ -53,12 +53,6 @@ async function makeDuplicate(gristDoc: GristDoc, pageId: number, pageName: strin
 | 
			
		||||
        results.map(res => res.sectionRef)
 | 
			
		||||
      ) as {[id: number]: number};
 | 
			
		||||
 | 
			
		||||
      // update layout spec
 | 
			
		||||
      const viewLayoutSpec = patchLayoutSpec(sourceView.layoutSpecObj.peek(), viewSectionIdMap);
 | 
			
		||||
      await gristDoc.docData.sendAction(
 | 
			
		||||
        ['UpdateRecord', '_grist_Views', viewRef, { layoutSpec: JSON.stringify(viewLayoutSpec)}]
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      // update the view fields
 | 
			
		||||
      const destViewSections = viewSections.map((vs) => (
 | 
			
		||||
        gristDoc.docModel.viewSections.rowModels[viewSectionIdMap[vs.getRowId()]]
 | 
			
		||||
@ -70,14 +64,48 @@ async function makeDuplicate(gristDoc: GristDoc, pageId: number, pageName: strin
 | 
			
		||||
        flatten(viewSections.map((vs) => vs.viewFields.peek().peek().map((field) => field.getRowId()))),
 | 
			
		||||
        flatten(newViewFieldIds)) as {[id: number]: number};
 | 
			
		||||
 | 
			
		||||
      // update the view sections
 | 
			
		||||
      await updateViewSections(gristDoc, destViewSections, viewSections, viewFieldsIdMap, viewSectionIdMap);
 | 
			
		||||
      // update layout spec
 | 
			
		||||
      const viewLayoutSpec = patchLayoutSpec(sourceView.layoutSpecObj.peek(), viewSectionIdMap);
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        gristDoc.docData.sendAction(
 | 
			
		||||
          ['UpdateRecord', '_grist_Views', viewRef, { layoutSpec: JSON.stringify(viewLayoutSpec)}]
 | 
			
		||||
        ),
 | 
			
		||||
        updateViewSections(gristDoc, destViewSections, viewSections, viewFieldsIdMap, viewSectionIdMap),
 | 
			
		||||
        copyFilters(gristDoc, viewSections, viewSectionIdMap)
 | 
			
		||||
      ]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  // Give copy focus
 | 
			
		||||
  await gristDoc.openDocPage(viewRef);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Copies _grist_Filters from source sections.
 | 
			
		||||
 */
 | 
			
		||||
async function copyFilters(
 | 
			
		||||
  gristDoc: GristDoc,
 | 
			
		||||
  srcViewSections: ViewSectionRec[],
 | 
			
		||||
  viewSectionMap: {[id: number]: number}) {
 | 
			
		||||
 | 
			
		||||
  // Get all filters for selected sections.
 | 
			
		||||
  const filters: RowRecord[] = [];
 | 
			
		||||
  const table = gristDoc.docData.getMetaTable('_grist_Filters');
 | 
			
		||||
  for (const srcViewSection of srcViewSections) {
 | 
			
		||||
    const sectionFilters = table
 | 
			
		||||
      .filterRecords({ viewSectionRef : srcViewSection.id.peek()})
 | 
			
		||||
      .map(filter => ({
 | 
			
		||||
        // Replace section ref with destination ref.
 | 
			
		||||
        ...filter, viewSectionRef : viewSectionMap[srcViewSection.id.peek()]
 | 
			
		||||
      }));
 | 
			
		||||
    filters.push(...sectionFilters);
 | 
			
		||||
  }
 | 
			
		||||
  if (filters.length) {
 | 
			
		||||
    const filterInfo = getColValues(filters);
 | 
			
		||||
    await gristDoc.docData.sendAction(['BulkAddRecord', '_grist_Filters',
 | 
			
		||||
      new Array(filters.length).fill(null), filterInfo]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update all of destViewSections with srcViewSections, use fieldsMap to patch the section layout
 | 
			
		||||
 * (for detail/cardlist sections), use viewSectionMap to patch the sections ids for linking.
 | 
			
		||||
@ -99,11 +127,9 @@ async function updateViewSections(gristDoc: GristDoc, destViewSections: ViewSect
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // transpose data
 | 
			
		||||
  const sectionsInfo = {} as BulkColValues;
 | 
			
		||||
  forEach(records[0], (val, key) => sectionsInfo[key] = records.map(rec => rec[key]));
 | 
			
		||||
  const sectionsInfo = getColValues(records);
 | 
			
		||||
 | 
			
		||||
  // ditch column ids and parentId
 | 
			
		||||
  delete sectionsInfo.id;
 | 
			
		||||
  // ditch column parentId
 | 
			
		||||
  delete sectionsInfo.parentId;
 | 
			
		||||
 | 
			
		||||
  // send action
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// Some definitions have moved to be part of plugin API.
 | 
			
		||||
import { CellValue } from 'app/plugin/GristData';
 | 
			
		||||
import { CellValue, RowRecord } from 'app/plugin/GristData';
 | 
			
		||||
export { CellValue, RowRecord } from 'app/plugin/GristData';
 | 
			
		||||
 | 
			
		||||
// Part of a special CellValue used for comparisons, embedding several versions of a CellValue.
 | 
			
		||||
@ -182,3 +182,23 @@ export function fromTableDataAction(tableData: TableDataAction): TableColValues
 | 
			
		||||
  const colValues: BulkColValues = tableData[3];
 | 
			
		||||
  return {id: rowIds, ...colValues};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert a list of rows into an object with columns of values, used for
 | 
			
		||||
 * BulkAddRecord/BulkUpdateRecord actions.
 | 
			
		||||
 */
 | 
			
		||||
export function getColValues(records: RowRecord[]): BulkColValues {
 | 
			
		||||
  const colIdSet = new Set<string>();
 | 
			
		||||
  for (const r of records) {
 | 
			
		||||
    for (const c of Object.keys(r)) {
 | 
			
		||||
      if (c !== 'id') {
 | 
			
		||||
        colIdSet.add(c);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  const result: BulkColValues = {};
 | 
			
		||||
  for (const colId of colIdSet) {
 | 
			
		||||
    result[colId] = records.map(r => r[colId]);
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user