Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InputChoiceSorting: Rework logic to work horizontally. #333

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,19 @@ export class InputCheckbox<CustomSurvey, CustomHousehold, CustomHome, CustomPers
const columnedChoiceInputs: JSX.Element[] = [];
for (let i = 0, count = widgetsByColumn.length; i < count; i++) {
const columnWidgets = widgetsByColumn[i];
columnedChoiceInputs.push(
<div className="survey-question__input-checkbox-group-column" key={i}>
{columnWidgets}
</div>
);
if (this.props.widgetConfig.alignment === 'vertical') {
columnedChoiceInputs.push(
<div className="survey-question__input-checkbox-group-column" key={i}>
{columnWidgets}
</div>
);
} else {
columnedChoiceInputs.push(
<div className="survey-question__input-checkbox-group-row" key={i}>
{columnWidgets}
</div>
);
}
}

return columnedChoiceInputs;
Expand Down Expand Up @@ -273,11 +281,15 @@ export class InputCheckbox<CustomSurvey, CustomHousehold, CustomHome, CustomPers
)
: null;

const shouldDisplayAsRows =
this.props.widgetConfig.alignment === undefined || this.props.widgetConfig.alignment === 'auto' || this.props.widgetConfig.alignment === 'vertical';
return (
<div
className={`survey-question__input-checkbox-group-container${
this.props.widgetConfig.sameLine === false ? ' no-wrap' : ''
}`}
className={`${
shouldDisplayAsRows
? 'survey-question__input-checkbox-group-container'
: 'survey-question__input-checkbox-group-container-column'
}${this.props.widgetConfig.sameLine === false ? ' no-wrap' : ''}`}
>
{columnedChoiceInputs}
{this.props.customId && (
Expand Down
166 changes: 25 additions & 141 deletions packages/evolution-frontend/src/components/inputs/InputChoiceSorting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,125 +6,64 @@
*/

/**
* Sort the array to be displayed to the target number of columns in vertical fashion.
* Sort the array in a specified count of groups.
* @param arr - Array to be sorted.
* @param columns - Target number of columns.
* @param count - Target number of group.
* @returns A 2 dimension array containing the data as columns to be displayed.
*
* @example
* // Prints [[0,1,2],[3,4,5]]
* console.log(verticalByColumns([0,1,2,3,4,5], 2));
* console.log(splitSort([0,1,2,3,4,5], 2));
*/
const verticalByColumns = function <Value>(arr: Value[], columns: number): Value[][] {
const splitSort = function <Value>(arr: Value[], count: number): Value[][] {
const len = arr.length;
const out: any[] = [];
let index = 0;
let columnIndex = 0;
let countPerColumn = Math.ceil(len / columns);
let countPerColumn = Math.ceil(len / count);
while (index + countPerColumn < len) {
out.push(arr.slice(index, (index += countPerColumn)));
columnIndex++;
countPerColumn = Math.ceil((len - index) / (columns - columnIndex));
countPerColumn = Math.ceil((len - index) / (count - columnIndex));
}
out.push(arr.slice(index));

return out;
};

/**
* Sort the array to be displayed to the target number of rows in vertical fashion.
* Sort the array in groups of specified length.
* @param arr - Array to be sorted
* @param rows - Target number of rows.
* @param length - Target number of item in group.
* @returns A 2 dimension array containing the data as columns to be displayed.
*
* @example
* // Prints [[0,1],[2,3],[4,5]]
* console.log(verticalByRows([0,1,2,3,4,5], 2));
* console.log(subsequentSort([0,1,2,3,4,5], 2));
*/
const verticalByRows = function <Value>(arr: Value[], rows: number): Value[][] {
const subsequentSort = function <Value>(arr: Value[], length: number): Value[][] {
const len = arr.length;
const out: any[] = [];
let index = 0;
while (index + rows < len) {
out.push(arr.slice(index, (index += rows)));
while (index + length < len) {
out.push(arr.slice(index, (index += length)));
}
out.push(arr.slice(index));

return out;
};

/**
* Sort the array to be displayed to the target number of columns in horizontal fashion
* Sort the array in groups of custom lengths.
* @param arr - Array to be sorted.
* @param columns - Target number of columns.
* @returns A 2 dimension array containing the data as columns to be displayed.
*
* @example
* // Prints [[0,2,4],[1,3,5]]
* console.log(horizontalByColumns([0,1,2,3,4,5], 2));
*/
const horizontalByColumns = function <Value>(arr: Value[], columns: number): Value[][] {
const len = arr.length;
const out: any[] = [];
let index = 0;
let columnIndex = 0;
let newColumn: any[] = [];
while (index < len) {
newColumn.push(arr[index]);
index += columns;
if (index >= len && columnIndex < columns) {
columnIndex++;
index = columnIndex;
out.push(newColumn);
newColumn = [];
}
}

return out;
};

/**
* Sort the array to be displayed to the target number of rows in horizontal fashion.
* @param arr - Array to be sorted.
* @param rows - Target number of rows.
* @returns A 2 dimension array containing the data as columns to be displayed.
*
* @example
* // Prints [[0,3],[1,4],[2,5]]
* console.log(horizontalByRows([0,1,2,3,4,5], 2));
*/
const horizontalByRows = function <Value>(arr: Value[], rows: number): Value[][] {
const len = arr.length;
const out: any[] = [];
let index = 0;
let columnIndex = 0;
const columns = Math.ceil(arr.length / rows);
let newColumn: any[] = [];
while (index < len) {
newColumn.push(arr[index]);
index += columns;
if (index >= len && columnIndex < columns) {
columnIndex++;
index = columnIndex;
out.push(newColumn);
newColumn = [];
}
}

return out;
};

/**
* Sort the array to be displayed in columns by the custom array information.
* @param arr - Array to be sorted.
* @param custom - Array containing the dedired length of each column.
* @param custom - Array containing the dedired length of each group.
* @returns A 2 dimension array containing the data as columns to be displayed.
*
* @example
* // Prints [[0,1,2],[3,4],[5]]
* console.log(customVertical([0,1,2,3,4,5], [3,2,1]));
* console.log(cusotmSort([0,1,2,3,4,5], [3,2,1]));
*/
const customVertical = function <Value>(arr: Value[], custom: number[]): Value[][] {
const customSort = function <Value>(arr: Value[], custom: number[]): Value[][] {
const len = arr.length;
const out: any[] = [];
let index = 0;
Expand All @@ -138,47 +77,6 @@ const customVertical = function <Value>(arr: Value[], custom: number[]): Value[]
return out;
};

/**
* Sort the array to be displayed in rows by the custom array information.
* @param arr - Array to be sorted.
* @param custom - Array containing the desired legnths of each row.
* @returns A 2 dimension array containing the data as columns to be displayed.
*
* @example
* // Prints [[0,3,5],[1,4],[2]]
* console.log(customHorizontal([0,1,2,3,4,5], [3,2,1]));
*/
const customHorizontal = function <Value>(arr: Value[], custom: number[]): Value[][] {
const len = arr.length;
const out: any[] = [];
let index = 0;
let columnIndex = 0;
let rowIndex = 0;
let newColumn: any[] = [];
while (index < len && columnIndex < custom[0]) {
if (columnIndex >= custom[rowIndex]) {
columnIndex++;
rowIndex = 0;
index = columnIndex;
out.push(newColumn);
newColumn = [];
continue;
}
newColumn.push(arr[index]);
index += custom[rowIndex];
rowIndex++;
if (index >= len || rowIndex >= custom[columnIndex]) {
columnIndex++;
rowIndex = 0;
index = columnIndex;
out.push(newColumn);
newColumn = [];
}
}

return out;
};

/**
* Sorts the array based on the specified parameters.
*
Expand All @@ -187,7 +85,7 @@ const customHorizontal = function <Value>(arr: Value[], custom: number[]): Value
*
* @param arr - Array to be sorted.
* @param alignement - In wich way should the array be sorted? Top to bottom or left to right.
* @param colums - Target amount of columns, if columns and rows are specified, columns is used.
* @param columns - Target amount of columns, if columns and rows are specified, columns is used.
* @param rows - target amount of rows, if columns and rows are specified, columns is used.
* @param customAlignmentLengths - Specify the lengths of each row or column individually, if alignement is horizontal, the first specified row must be the longuest.
* @returns A 2 dimension array containing the input array sorted into columns for display or the original array in case of invalid parameters.
Expand All @@ -200,41 +98,27 @@ const sortByParameters = function <Value>(
customAlignmentLengths?: number[]
): Value[][] {
if (customAlignmentLengths && customAlignmentLengths.length > 0) {
switch (alignment) {
case 'vertical':
return customVertical(arr, customAlignmentLengths);
case 'horizontal':
return customHorizontal(arr, customAlignmentLengths);
default:
return customVertical(arr, customAlignmentLengths);
}
return customSort(arr, customAlignmentLengths);
} else if (columns && columns > 0) {
switch (alignment) {
case 'vertical':
return verticalByColumns(arr, columns);
return splitSort(arr, columns);
case 'horizontal':
return horizontalByColumns(arr, columns);
return subsequentSort(arr, columns);
default:
return verticalByColumns(arr, columns);
return splitSort(arr, columns);
}
} else if (rows && rows > 0) {
switch (alignment) {
case 'vertical':
return verticalByRows(arr, rows);
return subsequentSort(arr, rows);
case 'horizontal':
return horizontalByRows(arr, rows);
return splitSort(arr, rows);
default:
return verticalByRows(arr, rows);
return subsequentSort(arr, rows);
}
} else {
switch (alignment) {
case 'vertical':
return verticalByColumns(arr, 2);
case 'horizontal':
return horizontalByRows(arr, 2);
default:
return verticalByColumns(arr, 2);
}
return splitSort(arr, 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iiuc, what this PR changes also is that the alignment is now the responsibility of the widget/css instead of this group sorting, as before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

}
};

Expand Down
29 changes: 21 additions & 8 deletions packages/evolution-frontend/src/components/inputs/InputRadio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,19 @@ export class InputRadio<CustomSurvey, CustomHousehold, CustomHome, CustomPerson>
const columnedChoiceInputs: JSX.Element[] = [];
for (let i = 0, count = widgetsByColumn.length; i < count; i++) {
const columnWidgets = widgetsByColumn[i];
columnedChoiceInputs.push(
<div className="survey-question__input-radio-group-column" key={i}>
{columnWidgets}
</div>
);
if (this.props.widgetConfig.alignment === 'vertical') {
columnedChoiceInputs.push(
<div className="survey-question__input-radio-group-column" key={i}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too, instead of the if-then-else, you can use

className=`survey-question__input-radio-group-{this.props.widgetConfig.alignment === undefined || this.props.widgetConfig.alignment === 'vertical' ? 'column' : 'row' }`

to avoid code duplication.

{columnWidgets}
</div>
);
} else {
columnedChoiceInputs.push(
<div className="survey-question__input-radio-group-row" key={i}>
{columnWidgets}
</div>
);
}
}
return columnedChoiceInputs;
};
Expand Down Expand Up @@ -298,11 +306,16 @@ export class InputRadio<CustomSurvey, CustomHousehold, CustomHome, CustomPerson>
));
// separate by columns if needed:
const columnedChoiceInputs = this.getColumnedChoices(choiceInputs);

const shouldDisplayAsRows =
this.props.widgetConfig.alignment === undefined || this.props.widgetConfig.alignment === 'auto' || this.props.widgetConfig.alignment === 'vertical';
return (
<div
className={`survey-question__input-radio-group-container${
this.props.widgetConfig.sameLine === false ? ' no-wrap' : ''
}`}
className={`${
shouldDisplayAsRows
? 'survey-question__input-radio-group-container'
: 'survey-question__input-radio-group-container-column'
}${this.props.widgetConfig.sameLine === false ? ' no-wrap' : ''}`}
>
{columnedChoiceInputs}
</div>
Expand Down
Loading