mirror of
				https://github.com/gristlabs/grist-core.git
				synced 2025-06-13 20:53:59 +00:00 
			
		
		
		
	(core) Filter linking by reference list columns
Summary: Use 'intersects' query operation when linking against a RefList column, otherwise the rest is the same as linking with a Ref column. Add RefList columns to Select By options along with Ref columns. Test Plan: Added new test and fixture similar to SelectBySummary Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2986
This commit is contained in:
		
							parent
							
								
									572b59cc0c
								
							
						
					
					
						commit
						54b932300b
					
				@ -2,6 +2,7 @@ const _ = require('underscore');
 | 
				
			|||||||
const ko = require('knockout');
 | 
					const ko = require('knockout');
 | 
				
			||||||
const dispose = require('../lib/dispose');
 | 
					const dispose = require('../lib/dispose');
 | 
				
			||||||
const gutil = require('app/common/gutil');
 | 
					const gutil = require('app/common/gutil');
 | 
				
			||||||
 | 
					const {isRefListType} = require("app/common/gristTypes");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Returns if the first table is a summary of the second. If both are summary tables, returns true
 | 
					 * Returns if the first table is a summary of the second. If both are summary tables, returns true
 | 
				
			||||||
@ -65,7 +66,10 @@ function LinkingState(gristDoc, srcSection, srcColId, tgtSection, tgtColId, byAl
 | 
				
			|||||||
  // A computed that evaluates to a filter function to use, or null if not filtering. If
 | 
					  // A computed that evaluates to a filter function to use, or null if not filtering. If
 | 
				
			||||||
  // filtering, depends on srcSection.activeRowId().
 | 
					  // filtering, depends on srcSection.activeRowId().
 | 
				
			||||||
  if (tgtColId) {
 | 
					  if (tgtColId) {
 | 
				
			||||||
 | 
					    const tgtCol = tgtSection.table().columns().all().find(c => c.colId() === tgtColId);
 | 
				
			||||||
 | 
					    const operations = {[tgtColId]: isRefListType(tgtCol.type()) ? 'intersects' : 'in'};
 | 
				
			||||||
    if (byAllShown) {
 | 
					    if (byAllShown) {
 | 
				
			||||||
 | 
					      // (This is legacy code that isn't currently reachable)
 | 
				
			||||||
      // Include all values present in srcSection.
 | 
					      // Include all values present in srcSection.
 | 
				
			||||||
      this.filterColValues = this.autoDispose(ko.computed(() => {
 | 
					      this.filterColValues = this.autoDispose(ko.computed(() => {
 | 
				
			||||||
        const srcValues = new Set();
 | 
					        const srcValues = new Set();
 | 
				
			||||||
@ -88,13 +92,13 @@ function LinkingState(gristDoc, srcSection, srcColId, tgtSection, tgtColId, byAl
 | 
				
			|||||||
        this.filterColValues = this.autoDispose(ko.computed(() => {
 | 
					        this.filterColValues = this.autoDispose(ko.computed(() => {
 | 
				
			||||||
          const srcRowId = srcSection.activeRowId();
 | 
					          const srcRowId = srcSection.activeRowId();
 | 
				
			||||||
          srcRowModel.assign(srcRowId);
 | 
					          srcRowModel.assign(srcRowId);
 | 
				
			||||||
          return {filters: {[tgtColId]: [srcCell()]}};
 | 
					          return {filters: {[tgtColId]: [srcCell()]}, operations};
 | 
				
			||||||
        }));
 | 
					        }));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      this.filterColValues = this.autoDispose(ko.computed(() => {
 | 
					      this.filterColValues = this.autoDispose(ko.computed(() => {
 | 
				
			||||||
        const srcRowId = srcSection.activeRowId();
 | 
					        const srcRowId = srcSection.activeRowId();
 | 
				
			||||||
        return {filters: {[tgtColId]: [srcRowId]}};
 | 
					        return {filters: {[tgtColId]: [srcRowId]}, operations};
 | 
				
			||||||
      }));
 | 
					      }));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else if (isSummaryOf(srcSection.table(), tgtSection.table())) {
 | 
					  } else if (isSummaryOf(srcSection.table(), tgtSection.table())) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import { ColumnRec, DocModel, ViewSectionRec } from 'app/client/models/DocModel';
 | 
					import { ColumnRec, DocModel, TableRec, ViewSectionRec } from 'app/client/models/DocModel';
 | 
				
			||||||
import { IPageWidget } from 'app/client/ui/PageWidgetPicker';
 | 
					import { IPageWidget } from 'app/client/ui/PageWidgetPicker';
 | 
				
			||||||
import { removePrefix } from 'app/common/gutil';
 | 
					import { getReferencedTableId } from 'app/common/gristTypes';
 | 
				
			||||||
import { IOptionFull } from 'grainjs';
 | 
					import { IOptionFull } from 'grainjs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// some unicode characters
 | 
					// some unicode characters
 | 
				
			||||||
@ -150,7 +150,6 @@ function createNodes(docModel: DocModel, sections: MaybeSection[]) {
 | 
				
			|||||||
// Creates an array of LinkNode from a view section record.
 | 
					// Creates an array of LinkNode from a view section record.
 | 
				
			||||||
function fromViewSectionRec(section: ViewSectionRec): LinkNode[] {
 | 
					function fromViewSectionRec(section: ViewSectionRec): LinkNode[] {
 | 
				
			||||||
  const table = section.table.peek();
 | 
					  const table = section.table.peek();
 | 
				
			||||||
  const columns = table.columns.peek().peek();
 | 
					 | 
				
			||||||
  const ancestors = new Set<number>();
 | 
					  const ancestors = new Set<number>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (let sec = section; sec.getRowId(); sec = sec.linkSrcSection.peek()) {
 | 
					  for (let sec = section; sec.getRowId(); sec = sec.linkSrcSection.peek()) {
 | 
				
			||||||
@ -170,16 +169,7 @@ function fromViewSectionRec(section: ViewSectionRec): LinkNode[] {
 | 
				
			|||||||
    section,
 | 
					    section,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const nodes: LinkNode[] = [mainNode];
 | 
					  return fromColumns(table, mainNode);
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // add the column nodes
 | 
					 | 
				
			||||||
  for (const column of columns) {
 | 
					 | 
				
			||||||
    const tableId = removePrefix(column.type.peek(), 'Ref:');
 | 
					 | 
				
			||||||
    if (tableId) {
 | 
					 | 
				
			||||||
      nodes.push({...mainNode, tableId, column});
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return nodes;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Creates an array of LinkNode from a page widget.
 | 
					// Creates an array of LinkNode from a page widget.
 | 
				
			||||||
@ -188,7 +178,6 @@ function fromPageWidget(docModel: DocModel, pageWidget: IPageWidget): LinkNode[]
 | 
				
			|||||||
  if (typeof pageWidget.table !== 'number') { return []; }
 | 
					  if (typeof pageWidget.table !== 'number') { return []; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const table = docModel.tables.getRowModel(pageWidget.table);
 | 
					  const table = docModel.tables.getRowModel(pageWidget.table);
 | 
				
			||||||
  const columns = table.columns.peek().peek();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const mainNode: LinkNode = {
 | 
					  const mainNode: LinkNode = {
 | 
				
			||||||
    tableId: table.primaryTableId.peek(),
 | 
					    tableId: table.primaryTableId.peek(),
 | 
				
			||||||
@ -198,16 +187,18 @@ function fromPageWidget(docModel: DocModel, pageWidget: IPageWidget): LinkNode[]
 | 
				
			|||||||
    section: docModel.viewSections.getRowModel(pageWidget.section),
 | 
					    section: docModel.viewSections.getRowModel(pageWidget.section),
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const nodes: LinkNode[] = [mainNode];
 | 
					  return fromColumns(table, mainNode);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // adds the column nodes
 | 
					function fromColumns(table: TableRec, mainNode: LinkNode): LinkNode[] {
 | 
				
			||||||
 | 
					  const nodes = [mainNode];
 | 
				
			||||||
 | 
					  const columns = table.columns.peek().peek();
 | 
				
			||||||
  for (const column of columns) {
 | 
					  for (const column of columns) {
 | 
				
			||||||
    const tableId = removePrefix(column.type.peek(), 'Ref:');
 | 
					    const tableId = getReferencedTableId(column.type.peek());
 | 
				
			||||||
    if (tableId) {
 | 
					    if (tableId) {
 | 
				
			||||||
      nodes.push({...mainNode, tableId, column});
 | 
					      nodes.push({...mainNode, tableId, column});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  return nodes;
 | 
					  return nodes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user