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

Feature: configurable custom file exports #533

Closed

Conversation

KarolakJakub
Copy link
Contributor

@KarolakJakub KarolakJakub commented Dec 10, 2019

This PR includes a feature that allows to create custom export options, as described in configuration.md - users will be able to add multiple configurable export types with different formatting, locales etc. If no defined exports are found within the config, Turnilo will use the default 'Export to TSV' and 'Export to CSV' ones.

Copy link
Collaborator

@adrianmroz adrianmroz left a comment

Choose a reason for hiding this comment

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

Some code style changes required but we should focus first on discussing shape of configuration. We have topic of localisation in different issue right now. Would be great if you could define which "localeOptions" are needed in your case - discussion about native vs numbro is still open.

}

public equals(other: ClassShareOptions): boolean {
return other instanceof ClassShareOptions && this.valueOf() === other.valueOf();
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's reference comparison, not equality check.

});
this.options = [...newOptionsCopy];
} else {
this.options = [...shareOptionsDefaults];
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why spread + array construction? Is it basically a this.options = shareOptionsDefaults equivalent?

locale?: Locales;
}

export type ShareOptions = ShareOption[];
Copy link
Collaborator

Choose a reason for hiding this comment

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

Using immutable List would simplify some code later.


if (options) {
const newOptionsCopy = options.map( option => {
option = { ...shareOptionsDefaults[1], ...option };
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why [1]? Whole merging code here is convoluted here.

finalLineBreak: "suppress",
columnOrdering: "keys-first",
lineBreak: "\r\n",
locale:
Copy link
Collaborator

Choose a reason for hiding this comment

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

We shouldn't confuse locale and formatting options. We need to design this API in clean way.

@@ -34,15 +37,13 @@ function findSeriesAndDerivation(name: string, concreteSeriesList: List<Concrete
return null;
}

export default function tabularOptions(essence: Essence): TabulatorOptions {
export default function tabularOptions(essence: Essence, locales?: Locales): TabulatorOptions {
Copy link
Collaborator

Choose a reason for hiding this comment

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

You use locales like it is required.

const type = `${getMIMEType(fileFormat)};charset=utf-8`;
const blob = new Blob([datasetToFileString(dataset, fileFormat, options)], { type });
if (!fileName) fileName = `${new Date()}-data`;
fileName += `.${fileFormat}`;
filesaver.saveAs(blob, fileName, true); // true == disable auto BOM
}

export function datasetToFileString(dataset: Dataset, fileFormat: FileFormat, options?: TabulatorOptions): string {
export function datasetToFileString(dataset: Dataset, fileFormat?: FileFormat, options?: TabulatorOptions): string {
const optionsCopy = { ...options };
Copy link
Collaborator

Choose a reason for hiding this comment

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

Possible spread on undefined.

@@ -37,19 +37,20 @@ export function getMIMEType(fileType: string) {
}
}

export function download({ dataset, options }: DataSetWithTabOptions, fileFormat: FileFormat, fileName?: string): void {
export function download({ dataset, options }: DataSetWithTabOptions, fileFormat: FileFormat, fileName?: string, custom?: boolean): void {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unused param

const { openOn, onClose } = props;

const { openOn, onClose, customization } = props;
const shareOptions = customization.shareOptions;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unused variable.

const dataSetWithTabOptions = getDownloadableDataset();

let dataSetWithTabOptions = getDownloadableDataset();
dataSetWithTabOptions.options = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Extract function that deals with construction of this object.

@adrianmroz
Copy link
Collaborator

Let's extract bug fix to another PR, so we could merge it earlier. Rest of it should wait till we discuss what is needed and how we should achieve it. For reference #504

@KarolakJakub
Copy link
Contributor Author

Bugfix extracted to #536

@KarolakJakub KarolakJakub changed the title Feature: configurable custom file exports, Bug fix for incorrect file formatting on consecutive exports Feature: configurable custom file exports Dec 12, 2019
Copy link
Member

@mkuthan mkuthan left a comment

Choose a reason for hiding this comment

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

The proposed direction for different export formats adds unnecessary complexity and will be confusing for end user. End user should export exactly what is presented on the screen, with preserved number and date formats. The Turnilo end users experiences will be consistent as it is now (I hope).


- title: "excel friendly export to TSV" # name displayed in the share menu
format: # "tsv" | "csv"
separator: # "\t" | "," | ...
Copy link
Member

Choose a reason for hiding this comment

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

What is the reason to define format AND separator? Format defines separator implicitly.

separator: # "\t" | "," | ...
lineBreak: "\r\n"
finalLineBreak: # "include" | "suppress"
columnOrdering: # "keys-first" | "as-seen";
Copy link
Member

Choose a reason for hiding this comment

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

Export should always preserve what is presented on the screen. If not user will be confused, please remember that end user is not aware of configuration.

lineBreak: "\r\n"
finalLineBreak: # "include" | "suppress"
columnOrdering: # "keys-first" | "as-seen";
locale:
Copy link
Member

Choose a reason for hiding this comment

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

As Adrian mentioned, there is open issue #504. And again, export should always preserve what is presented on the screen. It applies also to number and date formats. If some formats are not currently available on UI we should focus to remove existing limitations and add more formatting options.

Turnilo should be easy to understand for end user. How to

Copy link
Contributor Author

@KarolakJakub KarolakJakub Dec 12, 2019

Choose a reason for hiding this comment

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

I've replied in the #504 . 👍
Thank you for review, I will apply and push requested changes soon.
Regarding exports reflecting what's presented on screen/app - please note that this is already not the case. Turnilo is modifying date format on export

TIME_RANGE: (range: TimeRange) => range.start.toISOString()
so we do get different values.

Consider this export made on latest master - data is in a different format and value is rounded up in the app view.
image

Comma used as decimal separator is our main business need - Turnilo uses dot to separate fractional part of a number which causes issues when opened in Excel in our locale (pl-PL).

Copy link
Member

Choose a reason for hiding this comment

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

Yep, date & number formats are fixed in CSV/TSV. Currently there is no way to configure format for date dimensions in Turnilo, so dates on UI are formatted in the most concise way. We also put some effort (#288) to keep date formatting consistent across whole app, the export is the only exception with ISO formatting.

On the other hand for metrics, administrator is able to configure default format and user is able to change the configured format on UI, but the formatting is totally ignored by export CSV/TSV :(

Right now I don't know how to design date/number formatting in consistent way. I feel convinced that formatting on UI and formatting in the exports could be different but the formatting is rather related to the given dimension/measure not to particular export.

Perhaps we should enhance existing formatting configuration to datetime and numeric dimensions in similar way to measures. But for sure start with good design before implementation step.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants