From 981f9af6068a66b543f33e30bea72a1e2642f528 Mon Sep 17 00:00:00 2001 From: Pierre Gonzalez Date: Tue, 25 Jun 2019 20:11:50 +0200 Subject: [PATCH 01/13] init form --- src/assets/schemas/sort-step__schema.json | 22 +++++++++ src/components/stepforms/SortStepForm.vue | 56 +++++++++++++++++++++++ src/components/stepforms/index.ts | 1 + 3 files changed, 79 insertions(+) create mode 100644 src/assets/schemas/sort-step__schema.json create mode 100644 src/components/stepforms/SortStepForm.vue diff --git a/src/assets/schemas/sort-step__schema.json b/src/assets/schemas/sort-step__schema.json new file mode 100644 index 0000000000..2027123617 --- /dev/null +++ b/src/assets/schemas/sort-step__schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Sort column step", + "type": "object", + "properties": { + "name": { + "type": "string", + "enum": ["delete"] + }, + "column": { + "type": "string", + "minLength": 1, + "title": "Column to sort", + "description": "Column to sort", + "attrs": { + "placeholder": "Enter a column" + } + } + }, + "required": ["name", "column"], + "additionalProperties": false +} diff --git a/src/components/stepforms/SortStepForm.vue b/src/components/stepforms/SortStepForm.vue new file mode 100644 index 0000000000..8c95801f5b --- /dev/null +++ b/src/components/stepforms/SortStepForm.vue @@ -0,0 +1,56 @@ + + + + diff --git a/src/components/stepforms/index.ts b/src/components/stepforms/index.ts index e89728a570..44abfb9e7d 100644 --- a/src/components/stepforms/index.ts +++ b/src/components/stepforms/index.ts @@ -10,3 +10,4 @@ import './PercentageStepForm.vue'; import './PivotStepForm.vue'; import './RenameStepForm.vue'; import './UnpivotStepForm.vue'; +import './SortStepForm.vue'; From aaa039a5f7f5bbbf659cf09ffe01757138bf2417 Mon Sep 17 00:00:00 2001 From: Pierre Gonzalez Date: Fri, 28 Jun 2019 18:27:54 +0200 Subject: [PATCH 02/13] add sort step to action menu, add form and change mongo transformation --- doc/steps.md | 45 +--------- src/assets/schemas/sort-step__schema.json | 31 +++++-- src/components/ActionMenu.vue | 1 + src/components/stepforms/SortStepForm.vue | 55 +++++++++--- src/components/stepforms/WidgetList.vue | 2 +- src/components/stepforms/WidgetSortColumn.vue | 88 +++++++++++++++++++ src/lib/steps.ts | 8 +- src/lib/translators/mongo.ts | 6 +- tests/unit/mongo.spec.ts | 24 +---- 9 files changed, 168 insertions(+), 92 deletions(-) create mode 100644 src/components/stepforms/WidgetSortColumn.vue diff --git a/doc/steps.md b/doc/steps.md index b517fb29a8..13e96a6f37 100644 --- a/doc/steps.md +++ b/doc/steps.md @@ -734,52 +734,16 @@ the `select` is used, it will only keep selected columns in the output. ### `sort` step Sort values in one or several columns. Order can be either 'asc' or 'desc'. -When sorting on several columns, order of columns specified in `columns` matters, -and the `order` parameter must be of same length as `columns`. By default, if -`order` is not specified, it is considered as 'asc'. +When sorting on several columns, order of columns specified in `columns` matters. ```javascript { name: 'sort', - columns: ['foo', 'bar'], - order: ['asc', 'desc'] + columns: [{column: 'foo', order: 'asc'}, {column: 'bar', order: 'desc'}], } ``` -#### Example 1: sort on one column with default ordering - -**Input dataset:** - -| Label | Group | Value | -| ------- | ------- | ----- | -| Label 1 | Group 1 | 13 | -| Label 2 | Group 1 | 7 | -| Label 3 | Group 1 | 20 | -| Label 4 | Group 2 | 1 | -| Label 5 | Group 2 | 10 | -| Label 6 | Group 2 | 5 | - -**Step configuration:** - -```javascript -{ - name: 'sort', - columns: ['Value'], -} -``` - -**Output dataset:** - -| Company | Group | Value | -| ------- | ------- | ----- | -| Label 4 | Group 2 | 1 | -| Label 6 | Group 2 | 5 | -| Label 2 | Group 1 | 7 | -| Label 5 | Group 2 | 10 | -| Label 1 | Group 1 | 13 | -| Label 3 | Group 1 | 20 | - -#### Example 2: sort on one column with default ordering +#### Example **Input dataset:** @@ -797,8 +761,7 @@ and the `order` parameter must be of same length as `columns`. By default, if ```javascript { name: 'sort', - columns: ['Group', 'Value'], - order: ['asc', 'desc'], + columns: [{ column: 'Group', order: 'asc'}, {column: 'Value', order: 'desc' }] } ``` diff --git a/src/assets/schemas/sort-step__schema.json b/src/assets/schemas/sort-step__schema.json index 2027123617..5af659c779 100644 --- a/src/assets/schemas/sort-step__schema.json +++ b/src/assets/schemas/sort-step__schema.json @@ -5,18 +5,33 @@ "properties": { "name": { "type": "string", - "enum": ["delete"] + "enum": ["sort"] }, - "column": { - "type": "string", - "minLength": 1, - "title": "Column to sort", - "description": "Column to sort", + "columns": { + "type": "array", + "minItems": 1, + "title": "Columns to sort", + "description": "Columns to sort", "attrs": { - "placeholder": "Enter a column" + "placeholder": "Enter columns" + }, + "items": { + "type": "object", + "title": "Column to sort", + "description": "Column to sort", + "properties": { + "column": { + "type": "string", + "minLength": 1 + }, + "order": { + "type": "string", + "enum": ["asc", "desc"] + } + } } } }, - "required": ["name", "column"], + "required": ["name", "columns"], "additionalProperties": false } diff --git a/src/components/ActionMenu.vue b/src/components/ActionMenu.vue index 5bac510d9b..d231bd3ae7 100644 --- a/src/components/ActionMenu.vue +++ b/src/components/ActionMenu.vue @@ -7,6 +7,7 @@
Delete column
Fill null values
Filter values
+
Sort values
diff --git a/src/components/stepforms/SortStepForm.vue b/src/components/stepforms/SortStepForm.vue index 8c95801f5b..3b35307425 100644 --- a/src/components/stepforms/SortStepForm.vue +++ b/src/components/stepforms/SortStepForm.vue @@ -1,16 +1,18 @@ @@ -22,6 +24,7 @@ import BaseStepForm from './StepForm.vue'; import { StepFormComponent } from '@/components/formlib'; import SortSchema from '@/assets/schemas/sort-step__schema.json'; import WidgetList from './WidgetList.vue'; +import { SortColumnType } from '@/lib/steps'; @StepFormComponent({ vqbstep: 'sort', @@ -31,22 +34,46 @@ import WidgetList from './WidgetList.vue'; }, }) export default class SortStepForm extends BaseStepForm { - @Prop({ type: Object, default: () => ({ name: 'sort', columns: [], order: [] }) }) + @Prop({ type: Object, default: () => ({ name: 'sort', columns: [] }) }) initialStepValue!: SortStep; readonly title: string = 'Edit Sort Step'; editedStepModel = SortSchema; + get defaultSortColumn() { + const sortColumn: SortColumnType = { + column: '', + order: 'asc', + }; + return sortColumn; + } + + get sortColumns() { + if (this.editedStep.columns.length) { + return this.editedStep.columns; + } else { + return [this.defaultSortColumn]; + } + } + + set sortColumns(newval) { + this.editedStep.columns = [...newval]; + } + get stepSelectedColumn() { - return this.editedStep.columns; + return this.editedStep.columns[this.editedStep.columns.length - 1]['column']; } set stepSelectedColumn(colname: string | null) { if (colname === null) { throw new Error('should not try to set null on filter "column" field'); } - if (colname !== null) { - this.editedStep.column = colname; + const sortColNames = []; + for (const column of this.editedStep.columns) { + sortColNames.push(column.column); + } + if (colname !== null && !sortColNames.includes(colname)) { + this.editedStep.columns.push({ column: colname, order: 'asc' }); } } } diff --git a/src/components/stepforms/WidgetList.vue b/src/components/stepforms/WidgetList.vue index f1206dac25..5ac4f8e7d0 100644 --- a/src/components/stepforms/WidgetList.vue +++ b/src/components/stepforms/WidgetList.vue @@ -155,4 +155,4 @@ export default class WidgetList extends Vue { top: calc(50% - 16px); cursor: pointer; } - \ No newline at end of file + diff --git a/src/components/stepforms/WidgetSortColumn.vue b/src/components/stepforms/WidgetSortColumn.vue new file mode 100644 index 0000000000..6a39327b09 --- /dev/null +++ b/src/components/stepforms/WidgetSortColumn.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/src/lib/steps.ts b/src/lib/steps.ts index fe58ce21bb..1b78997052 100644 --- a/src/lib/steps.ts +++ b/src/lib/steps.ts @@ -106,10 +106,14 @@ export type SelectStep = { columns: string[]; }; +export type SortColumnType = { + column: string; + order: 'asc' | 'desc'; +}; + export type SortStep = { name: 'sort'; - columns: string[]; - order?: ('asc' | 'desc')[]; + columns: SortColumnType[]; }; export type TopStep = { diff --git a/src/lib/translators/mongo.ts b/src/lib/translators/mongo.ts index 4e90ffc4ef..89af92e8cc 100644 --- a/src/lib/translators/mongo.ts +++ b/src/lib/translators/mongo.ts @@ -248,10 +248,8 @@ function transformReplace(step: Readonly): MongoStep { /** transform a 'sort' step into corresponding mongo steps */ function transformSort(step: Readonly): MongoStep { const sortMongo: PropMap = {}; - const sortOrders = step.order === undefined ? Array(step.columns.length).fill('asc') : step.order; - for (let i = 0; i < step.columns.length; i++) { - const order = sortOrders[i] === 'asc' ? 1 : -1; - sortMongo[step.columns[i]] = order; + for (const sortColumn of step.columns) { + sortMongo[sortColumn.column] = sortColumn.order === 'asc' ? 1 : -1; } return { $sort: sortMongo }; } diff --git a/tests/unit/mongo.spec.ts b/tests/unit/mongo.spec.ts index f6c127b929..4439caff25 100644 --- a/tests/unit/mongo.spec.ts +++ b/tests/unit/mongo.spec.ts @@ -471,8 +471,7 @@ describe('Pipeline to mongo translator', () => { const pipeline: Pipeline = [ { name: 'sort', - columns: ['foo'], - order: ['desc'], + columns: [{ column: 'foo', order: 'desc' }], }, ]; const querySteps = mongo36translator.translate(pipeline); @@ -489,8 +488,7 @@ describe('Pipeline to mongo translator', () => { const pipeline: Pipeline = [ { name: 'sort', - columns: ['foo', 'bar'], - order: ['asc', 'desc'], + columns: [{ column: 'foo', order: 'asc' }, { column: 'bar', order: 'desc' }], }, ]; const querySteps = mongo36translator.translate(pipeline); @@ -504,24 +502,6 @@ describe('Pipeline to mongo translator', () => { ]); }); - it('can generate a sort step on multiple columns with default order', () => { - const pipeline: Pipeline = [ - { - name: 'sort', - columns: ['foo', 'bar'], - }, - ]; - const querySteps = mongo36translator.translate(pipeline); - expect(querySteps).to.eql([ - { - $sort: { - foo: 1, - bar: 1, - }, - }, - ]); - }); - it('can generate a fillna step', () => { const pipeline: Pipeline = [ { From 4c4a40bb673496b1cd6103a4dc4c01992707bf74 Mon Sep 17 00:00:00 2001 From: Pierre Gonzalez Date: Tue, 2 Jul 2019 16:12:05 +0200 Subject: [PATCH 03/13] cleaning sort step form and add test edited step if columns don't exist --- src/components/stepforms/SortStepForm.vue | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/stepforms/SortStepForm.vue b/src/components/stepforms/SortStepForm.vue index 3b35307425..3290d7387f 100644 --- a/src/components/stepforms/SortStepForm.vue +++ b/src/components/stepforms/SortStepForm.vue @@ -1,11 +1,10 @@