Skip to content

Commit

Permalink
[Feature] Matchy v0
Browse files Browse the repository at this point in the history
In this commit:
- the user can create his options with conditions
- upload a csv file
- match the file header with the created options
- validation according to the conditions is done once submitting
- cells are colored red if not valid
- the user can edit diretly a cell value
- the color is updated to red if it's valid
- the user can delete a line

co-authored:
-Mahdi Cheikhrouhou
-Abderraouf Ghrissi
  • Loading branch information
RaoufGhrissi committed Sep 11, 2024
0 parents commit 9151790
Show file tree
Hide file tree
Showing 22 changed files with 1,252 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
225 changes: 225 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
# Matchy Library

This library provides functionality to upload CSV files, match the file header with existing options, and validate the contents of the CSV files based on predefined conditions. The validation includes checking for mandatory fields, maximum or minimum length, and data type (string, integer, boolean, float, or regex pattern).

## Features

1- Upload CSV files

2- Match file header with existing options

3- Validate cells based on conditions

4- Directly update cells without altering the file

5- Visual indication of validation status (red for invalid, green for valid)

## Overview

##### Option fields:

`display_value`: This field represents the value displayed to users. For instance, if the field represents a person's first name, the display_value might be "First Name".

`value`: The value field corresponds to the actual field name or identifier used in your database or backend systems. For example, if the field represents a person's first name and the database column is named "first_name", then value would be "first_name".

`mandatory`: This is a boolean field indicating whether the field is mandatory or required. If mandatory is set to true, it means that the field must have a value provided for it to be considered valid.

`type`: The type field specifies the data type of the field. It is typically represented by an enumeration Field Type with possible values (float, integer, string)

`conditions`: This field represents an array of conditions that need to be satisfied for the field to be considered valid.

##### Condition fields:

`property`: This field is an enum representing the property of the data being evaluated in the condition. It can take one of three values:

- **value**: Indicates that the condition applies directly to the value itself.
- **regex**: Specifies that the condition involves a regular expression pattern match.
- **length**: Denotes that the condition pertains to the length of the value, such as string length or array length.

`comparer`: This field is an enum representing the comparison operation to be applied in the condition. It can take one of six values:

- **gt**: Greater than comparison.
- **gte**: Greater than or equal to comparison.
- **lt**: Less than comparison.
- **lte**: Less than or equal to comparison.
- **e**: Equality comparison.
- **in**: Membership comparison, checking if the value exists in a specified list or range.
value: This field represents the value against which the condition is evaluated. It can be a number, a string, or an array of strings. The type of value depends on the context of the condition and the property being evaluated.

`custom_fail_message`: This field contains a custom failure message that can be displayed if the condition is not met. It is optional and can be either a string or null. If provided, this message overrides any default failure message associated with the condition.

These fields collectively define the criteria for validating data against specific conditions. They allow for flexible and customizable validation rules to ensure that data meets the required criteria within the application.

## Using Matchy with Angular
First you need to copy the `src` folder from this repository to your angular app.

In this example, this is my project structure
![alt text](image-4.png)

1- create a new componenet
2- your html file
```html
<div id="matchy"></div>
```
2- in your TS file

```ts
import { Component, OnInit } from '@angular/core';
import { Matchy } from 'src/libs/matchy/src/main';
import { Condition } from 'src/libs/matchy/src/models/classes/condition';
import { Option } from 'src/libs/matchy/src/models/classes/option';
import { Comparer } from 'src/libs/matchy/src/models/enums/comparer';
import { ConditonProperty } from 'src/libs/matchy/src/models/enums/conditon_property';
import { FieldType } from 'src/libs/matchy/src/models/enums/field_type';


@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class MyComponent implements OnInit {
title = 'matchy_test';

ngOnInit() {
const options = [
new Option("First Name", "first_name", true, FieldType.string, [
new Condition(ConditonProperty.length, 20, Comparer.gte),
new Condition(ConditonProperty.length, 30, Comparer.lt, "not safe choice"),
]),
new Option("Last Name", "last_name", true, FieldType.string, [
new Condition(ConditonProperty.value, ["AA", "BB"], Comparer.in)
]),
new Option("Age", "age", true, FieldType.integer, [
new Condition(ConditonProperty.value, 0, Comparer.gte),
new Condition(ConditonProperty.value, 40, Comparer.lte),
]),
new Option("Registration Number", "registration_num", true, FieldType.string, [
new Condition(ConditonProperty.regex, '^\\d{8}-\\d{2}$'),
]),
new Option("%", "percentage", true, FieldType.float, [
new Condition(ConditonProperty.value, 0, Comparer.gte),
new Condition(ConditonProperty.value, 100, Comparer.lte),
]),
];

const matchy = new Matchy(options);

document.getElementById("matchy")?.appendChild(matchy);
}
}
```

## Using Matchy with React

1- create a TS file containg some classes and enums to be able to create the options or copy them directly from src folder.

```ts
export enum Comparer {
gt = "gt",
gte = "gte",
lt = "lt",
lte = "lte",
e = "e",
in = "in",
}

export enum ConditonProperty {
value = "value",
regex = "regex",
length = "length",
}

export enum FieldType {
float = "float",
integer = "integer",
string = "string",
bool = "bool",
}

export class Condition {
property: ConditonProperty;
comparer: Comparer;
value: number | string | string[];
custom_fail_message: string | null;

constructor(property: ConditonProperty, value: number | string | string[], comparer: Comparer = Comparer.e, custom_fail_message: string | null = null) {
this.property = property;
this.comparer = comparer;
this.value = value;
this.custom_fail_message = custom_fail_message;
}
}

export class Option {
display_value: string;
value: string | null;
mandatory: boolean;
type: FieldType;
conditions: Condition[];

constructor(display_value: string = "", value: string | null = null, mandatory: boolean = false, type: FieldType = FieldType.string, conditions: Condition[] = []) {
this.display_value = display_value;
this.mandatory = mandatory;
this.type = type;
this.value = value;
this.conditions = conditions;
}
}

```

2- Create the component which will use matchy

```ts
import { Matchy } from "path_to_matchy/src/main";
import { useEffect, useRef } from "react";
import { Condition, Option, Comparer, ConditonProperty, FieldType} from 'path_to_condition/condition';

const ComponentWithMatchy = () => {
const matchyRef = useRef(null);
const options = [
new Option("First Name", "first_name", true, FieldType.string, [
new Condition(ConditonProperty.length, 20, Comparer.gte),
new Condition(ConditonProperty.length, 30, Comparer.lt, "not safe choice"),
]),
new Option("Last Name", "last_name", true, FieldType.string, [
new Condition(ConditonProperty.value, ["AA", "BB"], Comparer.in)
]),
new Option("Age", "age", true, FieldType.integer, [
new Condition(ConditonProperty.value, 0, Comparer.gte),
new Condition(ConditonProperty.value, 40, Comparer.lte),
]),
new Option("Registration Number", "registration_num", true, FieldType.string, [
new Condition(ConditonProperty.regex, '^\\d{8}-\\d{2}$'),
]),
new Option("%", "percentage", true, FieldType.float, [
new Condition(ConditonProperty.value, 0, Comparer.gte),
new Condition(ConditonProperty.value, 100, Comparer.lte),
]),
];
useEffect(() => {
const matchy_div = document.getElementById("matchy");
if (matchy_div) {
if (!matchy_div.querySelector("app-matchy")) {
// To prevent inserting 2 times in case you have React.StrictMode
matchy_div.appendChild(new Matchy(options));
}
}
}, []);
return (
<div id="matchy" ref={matchyRef}></div>
</>
);
};

export default ComponentWithMatchy;

```

## Contributing
Contributions are welcome! Please feel free to submit a pull request.
Check contributions.md for more details

## Support
For any questions or issues, please open an issue.
57 changes: 57 additions & 0 deletions contributions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Contribution Guidelines

Thank you for considering contributing to the Matchy project! We welcome contributions from everyone, whether it's reporting bugs, fixing issues, or adding new features. Your contributions help improve the library for everyone.

Ways to Contribute
There are several ways to contribute:

Report Bugs: If you encounter any bugs or unexpected behavior, please open an issue on our issue tracker.
Fix Issues: You can browse through the open issues on our issue tracker and pick any issue you'd like to work on. If you fix an issue, please submit a pull request.
Add Features: Have an idea for a new feature? Feel free to implement it and submit a pull request.
Improve Documentation: Documentation is crucial for a successful project. If you find any gaps or errors in the documentation, please help improve it.
Review Pull Requests: Reviewing pull requests is a valuable way to contribute. Your feedback can help ensure the quality and correctness of contributions.
Spread the Word: If you find the Matchy library useful, consider spreading the word about it. Share it with your friends, colleagues, or on social media.

Getting Started
If you're new to contributing to open-source projects or to Git and GitHub, don't worry! Here's how you can get started:

Fork the Repository: Click the "Fork" button on the top right corner of the repository's page to create your copy of the project.
Clone the Repository: Clone the repository to your local machine using Git:

git clone https://github.com/RaoufGhrissi/matchy

Create a Branch: Create a new branch for your work. Choose a descriptive name that summarizes the purpose of your changes:

```
git checkout -b feature/add-new-validation
```
Make Changes: Make your changes to the codebase. Ensure that your changes adhere to the coding standards and conventions used in the project.

Do your changes in src folder in ts files then run
```
tsc
```
to generate an updated dist folder with your new changes.

Test Your Changes: Test your changes thoroughly to ensure that they work as expected and do not introduce any regressions.
Commit Your Changes: Once you're satisfied with your changes, commit them to your branch:

```
git add .
git commit -m "Add new validation feature"
```
Push Your Changes: Push your changes to your forked repository on GitHub:
```
git push origin feature/add-new-validation
```
Submit a Pull Request: Go to the GitHub page of your forked repository, select your branch, and click the "Pull Request" button to submit your changes for review.
Code Style and Guidelines
Please follow the existing code style and guidelines used in the project. This helps maintain consistency and readability across the codebase.

Code of Conduct
We expect all contributors to adhere to the project's Code of Conduct. Please be respectful and considerate towards others.

Feedback
If you have any feedback or suggestions on how we can improve the contribution process, please let us know. We're always looking for ways to make it easier for people to contribute to the project.

Thank you for contributing to the CSV Validator project! 🎉
Binary file added image-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div class="container">
<h1>Upload CSV File</h1>
<app-matchy><app-matchy/>
</div>
<script type="module" src="./dist/main.js"></script>
</body>
</html>
48 changes: 48 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "csv_matchy",
"version": "1.0.1",
"description": "This library provides functionality to upload CSV files, match the file header with existing options, and validate the contents of the CSV files based on predefined conditions. The validation includes checking for mandatory fields, maximum or minimum length, and data type (string, integer, boolean, float, or regex pattern).",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/RaoufGhrissi/matchy.git"
},
"keywords": [
"csv",
"validator"
],
"author": "Mahdi Cheikhrouhou & Abderraouf Ghrissi",
"license": "ISC",
"bugs": {
"url": "https://github.com/RaoufGhrissi/matchy/issues"
},
"homepage": "https://github.com/RaoufGhrissi/matchy#readme",
"dependencies": {
"papaparse": "^5.4.1"
},
"devDependencies": {
"@types/papaparse": "^5.3.14"
}
}
Loading

0 comments on commit 9151790

Please sign in to comment.