Skip to content

Commit

Permalink
feat(datagrid): component MVP (#225)
Browse files Browse the repository at this point in the history
* feat(datagrid): start component with min attributes

* fix(datagrid): typo

* feat(datagrid): add more attributes

* fix(datagrid): doc with new props

* chore(datagrid): version

* feat(datagrid): style

* fix(datagrid): more test & props typo & pr ajustement

* fix(datagrid): border & row height

* fix(datagrid): ajustement style

* fix(datagrid): sort icon placement

* chore(datagrid): version

* chore(datagrid): update stencil 4

* fix(datagrid): lint

* feat(datagrid): step 4

* feat(datagrid): start component with min attributes

* feat(datagrid): formatter custom

* feat(datagrid): add large rows on storybook

* fix(datagrid): bad perf on rendered rows

* fix(datagrid): add height attributes

* fix(datagrid): review

* fix(datagrid): cursor

* fix(datagrid): pr review

* feat(datagrid): formatter custom

* feat(datagrid): add hidable columns setting

* fix(datagrid): popover click outside & row

* fix(datagrid): review style

* feat(datagrid): add has hideable columns props

* fix(datagrid): safari webkit

* fix(datagrid): typo & test

* fix(datagrid): isSelectable & event & hideableColumns

* chore(datagrid): version 16.3.1

* fix(datagrid): test & lint

* docs(datagrid): adapte dacs to the new structure

* fix(datagrid): icons & isSelectable toggle

* docs(datagrid): doc with menu & formatter

* chore(datagrid): version 16.3.2

* fix(datagrid): update table holder calculated size on render (#280)

---------

Co-authored-by: Damien Pellier <[email protected]>
  • Loading branch information
aesteves60 and dpellier authored Nov 16, 2023
1 parent 8098e22 commit 8156c4c
Show file tree
Hide file tree
Showing 57 changed files with 1,936 additions and 8 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"no-await-in-loop": "error",
"no-console": "error",
"no-extra-bind": "error",
"no-magic-numbers": "off",
"no-multi-spaces": "error",
"no-multiple-empty-lines": ["error", { "max": 1 }],
"no-nested-ternary": "error",
Expand Down
15 changes: 15 additions & 0 deletions packages/common/core/src/utils/string/parse-string-to-array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function parseStringToArray<T>(values: T[] | string, onError?: (err: unknown) => void): T[] {
if (typeof values === 'string') {
try {
return JSON.parse(values);
} catch (err) {
onError?.(err);
return [];
}
}
return [...values];
}

export {
parseStringToArray,
}
1 change: 1 addition & 0 deletions packages/common/core/src/utils/string/public-api.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './ods-get-src';
export * from './ods-is-src';
export * from './parse-string-to-array';
2 changes: 1 addition & 1 deletion packages/common/testing/src/helpers/attribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function odsStringAttributes2Str(attributes: Record<string, string | undefined>)
const kebabName = name.replace(/([a-z])([A-Z])/g, '$1-$2')
.replace(/[\s_]+/g, '-')
.toLowerCase();
return value === undefined ? `${kebabName}` : `${kebabName}="${value}"`;
return value === undefined ? `${kebabName}` : `${kebabName}='${value}'`;
})
.join(' ');
}
Expand Down
33 changes: 33 additions & 0 deletions packages/components/datagrid/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
dist/
custom-elements/
custom-elements-bundle/
www/
loader/
docs-api
src/components.d.ts

*~
*.sw[mnpcod]
*.log
*.lock
*.tmp
*.tmp.*
log.txt
*.sublime-project
*.sublime-workspace

.stencil/
screenshot/
.idea/
.vscode/
.sass-cache/
.versions/
node_modules/
$RECYCLE.BIN/

.DS_Store
Thumbs.db
UserInterfaceState.xcuserstate
.env

src/**/readme.md
4 changes: 4 additions & 0 deletions packages/components/datagrid/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
!dist/
!loader/
!docs-api/
src/
Empty file.
5 changes: 5 additions & 0 deletions packages/components/datagrid/THIRD-PARTY-LICENCES
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This file was generated with the generate-license-file npm package!
https://www.npmjs.com/package/generate-license-file

This file was generated with the generate-license-file npm package!
https://www.npmjs.com/package/generate-license-file
33 changes: 33 additions & 0 deletions packages/components/datagrid/documentation/specifications/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
* [**Interfaces**](#interfaces)
* [**Classes**](#classes)

## Interfaces

### OdsDatagridAttribute
|Name | Type | Required | Default | Description|
|---|---|:---:|---|---|
|**`columns`** | `string` \| `OdsDatagridColumn[]` | ✴️ | | The list of the column|
|**`hasHideableColumns`** | _boolean_ | | | Can you hide columns|
|**`height`** | _number_ | ✴️ | | Height of the datagrid, in pixel|
|**`hideableColumns`** | string[] | | | List of the hide columnsThe key need to be according to the column field|
|**`isSelectable`** | _boolean_ | | | The rows can be selectable|
|**`noResultLabel`** | _string_ | | | Text when the datagrid was no rows|
|**`rowHeight`** | _number_ | | | Height for each row, in pixel|
|**`rows`** | `string` \| `OdsDatagridRow[]` | ✴️ | | The list of the rowsThe key need to be according to the column field|

### OdsDatagridColumn
|Name | Type | Required | Default | Description|
|---|---|:---:|---|---|
|**`field`** | _string_ | ✴️ | | |
|**`isSortable`** | _boolean_ | | | |
|**`title`** | _string_ | ✴️ | | |
|**`formatter`** | _string_ | | | |

### OdsDatagridRow
|Key | Type | Description|
|---|:---:|---|
|_string_ | _unknown_ | |

## Classes

### OsdsDatagrid
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {Description} from '@storybook/addon-docs';
import Specs from './spec.md';

<Description>{Specs}</Description>

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
:root {
--ods-menu-position: absolute;
--ods-select-position: absolute;
--ods-popover-position: absolute;
--ods-tooltip-position: absolute;
}
250 changes: 250 additions & 0 deletions packages/components/datagrid/documentation/usage-guidelines/usage.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
import GenericStyle from '@ovhcloud/ods-common-core/docs/generic-style.mdx';
import './usage-style.css';
<GenericStyle />

## Usage

### Default with string
<osds-datagrid columns='[{"title":"Name","field":"name"},{"title":"Firstname","field":"firstname"},{"title":"Gender","field":"gender"},{"title":"Date Of Birth","field":"dob"}]'
rows='[{"name":"Dupont","firstname":"Antoine","gender":"male","dob":"15/11/1996"},{"name":"Garnbret","firstname":"Janja","gender":"female","dob":"12/03/1999"}]'
height="150"></osds-datagrid>

```html
<!-- Attributes need to be stringify -->
<osds-datagrid columns='[{"title":"Name","field":"name"},{"title":"Firstname","field":"firstname"},{"title":"Gender","field":"gender"},{"title":"Date Of Birth","field":"dob"}]'
rows='[{"name":"Dupont","firstname":"Antoine","gender":"male","dob":"15/11/1996"},{"name":"Garnbret","firstname":"Janja","gender":"female","dob":"12/03/1999"}]'
height="150"></osds-datagrid>
```

### Default with js
<osds-datagrid columns='[{"title":"Name","field":"name"},{"title":"Firstname","field":"firstname"},{"title":"Gender","field":"gender"},{"title":"Date Of Birth","field":"dob"}]'
rows='[{"name":"Dupont","firstname":"Antoine","gender":"male","dob":"15/11/1996"},{"name":"Garnbret","firstname":"Janja","gender":"female","dob":"12/03/1999"}]'
height="150"></osds-datagrid>

```html
<osds-datagrid id="datagrid"></osds-datagrid>

<script>
const datagrid = document.querySelector('#datagrid')
datagrid.columns = [
{ title: "Name", field: "name" },
{ title: "Firstname", field: "firstname" },
{ title: "Gender", field: "gender" },
{ title: "Date Of Birth", field: "dob" },
];
datagrid.rows = [
{ name: "Dupont", firstname: "Antoine", gender: "male", dob: "15/11/1996" },
{ name: "Garnbret", firstname: "Janja", gender: "female", dob: "12/03/1999" },
];
datagrid.height = 150;
</script>
```

### Selectable columns
<osds-datagrid
columns='[{"title":"Name","field":"name"},{"title":"Firstname","field":"firstname"},{"title":"Gender","field":"gender"},{"title":"Date Of Birth","field":"dob"}]'
rows='[{"name":"Dupont","firstname":"Antoine","gender":"male","dob":"15/11/1996"},{"name":"Garnbret","firstname":"Janja","gender":"female","dob":"12/03/1999"}]'
is-selectable
height="150">
</osds-datagrid>

```html
<!-- Attributes need to be stringify -->
<osds-datagrid
columns='[{"title":"Name","field":"name"},{"title":"Firstname","field":"firstname"},{"title":"Gender","field":"gender"},{"title":"Date Of Birth","field":"dob"}]'
rows='[{"name":"Dupont","firstname":"Antoine","gender":"male","dob":"15/11/1996"},{"name":"Garnbret","firstname":"Janja","gender":"female","dob":"12/03/1999"}]'
is-selectable
height="150">
</osds-datagrid>
```

### With sortable columns
<osds-datagrid
columns='[{"title":"Name","field":"name", "isSortable": true},{"title":"Firstname","field":"firstname"},{"title":"Gender","field":"gender"},{"title":"Date Of Birth","field":"dob"}]'
rows='[{"name":"Dupont","firstname":"Antoine","gender":"male","dob":"15/11/1996"},{"name":"Garnbret","firstname":"Janja","gender":"female","dob":"12/03/1999"}]'
height="150">
</osds-datagrid>

```html
<osds-datagrid id="datagrid"></osds-datagrid>

<script>
const datagrid = document.querySelector('#datagrid')
datagrid.columns = [
{ title: "Name", field: "name", isSortable: true },
{ title: "Firstname", field: "firstname" },
{ title: "Gender", field: "gender" },
{ title: "Date Of Birth", field: "dob" },
];
datagrid.rows = [
{ name: "Dupont", firstname: "Antoine", gender: "male", dob: "15/11/1996" },
{ name: "Garnbret", firstname: "Janja", gender: "female", dob: "12/03/1999" },
];
datagrid.height = 150;
</script>
```

### With Formatter

export const datagridFormatter = () => {
setTimeout(() => {
const datagrid = document.getElementById('datagridWithFormatter');
if (!datagrid) {
return;
}
datagrid.columns = [
{ title: "Name", field: "name", isSortable: true },
{ title: "Firstname", field: "firstname" },
{ title: "Gender", field: "gender" },
{ title: "Date Of Birth", field: "dob", formatter: (value) => {
return '<osds-icon name="calendar"></osds-icon> <osds-text color="text" size="400">' + value + '</osds-text>'
}
},
];
datagrid.rows = [
{ name: "Dupont", firstname: "Antoine", gender: "male", dob: "15/11/1996" },
{ name: "Garnbret", firstname: "Janja", gender: "female", dob: "12/03/1999" },
];
datagrid.height = 150;
}, 0);
};

<osds-datagrid id="datagridWithFormatter">
</osds-datagrid>

<>{ datagridFormatter() }</>

```html
<osds-datagrid id="datagrid"></osds-datagrid>

<script>
const datagrid = document.querySelector('#datagrid')
datagrid.columns = [
{ title: "Name", field: "name", isSortable: true },
{ title: "Firstname", field: "firstname" },
{ title: "Gender", field: "gender" },
{ title: "Date Of Birth", field: "dob", formatter: (value) => {
return '<osds-icon name="calendar"></osds-icon> <osds-text color="text" size="400"> ' + value + '</osds-text>'
}
},
];
datagrid.rows = [
{ name: "Dupont", firstname: "Antoine", gender: "male", dob: "15/11/1996" },
{ name: "Garnbret", firstname: "Janja", gender: "female", dob: "12/03/1999" },
];
datagrid.height = 150;
</script>
```

### Empty rows
<osds-datagrid
columns='[{"title":"Name","field":"name", "isSortable": true},{"title":"Firstname","field":"firstname"},{"title":"Gender","field":"gender"},{"title":"Date Of Birth","field":"dob"}]'
rows='[]'
no-result-label="Aucun résultat"
height="150">
</osds-datagrid>

```html
<osds-datagrid id="datagrid" no-result-label="Aucun résultat"></osds-datagrid>

<script>
const datagrid = document.querySelector('#datagrid')
datagrid.columns = [
{ title: "Name", field: "name", isSortable: true },
{ title: "Firstname", field: "firstname" },
{ title: "Gender", field: "gender" },
{ title: "Date Of Birth", field: "dob" },
];
datagrid.rows = [];
datagrid.height = 150;
</script>
```

### Use Select, Tooltip, Menu or Popover in row formatter

export const datagridWithMenu = () => {
setTimeout(() => {
const datagrid = document.getElementById('datagridWithMenu');
if (!datagrid) {
return;
}
datagrid.columns = [
{ title: "Name", field: "name", formatter: (cellValue, rowValue) => {
return `<osds-menu>
<osds-button slot="menu-title" color="primary" variant="stroked">
Action menu
<osds-icon name="home" size="xs"></osds-icon>
</osds-button>
<osds-menu-item>
<osds-button
color="primary"
size="sm"
variant="ghost"
text-align="start"
flex=""
>
<span>Action 1</span>
</osds-button>
</osds-menu-item>
</osds-menu>`
}
},
{ title: "Firstname", field: "firstname", isSortable: true },
{ title: "Gender", field: "gender", isSortable: true },
{ title: "Date Of Birth", field: "dob", isSortable: true },
];
datagrid.rows = [
{ name: "Dupont", firstname: "Antoine", gender: "male", dob: "15/11/1996" },
{ name: "Garnbret", firstname: "Janja", gender: "female", dob: "12/03/1999" },
];
datagrid.height = 150;
}, 0);
};

<osds-datagrid id="datagridWithMenu">
</osds-datagrid>

<>{ datagridWithMenu() }</>

```html
<osds-datagrid id="datagrid" no-result-label="Aucun résultat"></osds-datagrid>

<style>
:root {
--ods-menu-position: absolute;
--ods-select-position: absolute;
--ods-popover-position: absolute;
--ods-tooltip-position: absolute;
}
</style>

<script>
const datagrid = document.querySelector('#datagrid')
datagrid.columns = [
{ title: "Name", field: "name", formatter: (cellValue, rowValue) => {
return `<osds-menu>
<osds-button slot="menu-title" color="primary" variant="stroked">
Action menu
<osds-icon name="home" size="xs"></osds-icon>
</osds-button>
<osds-menu-item>
<osds-button
color="primary"
size="sm"
variant="ghost"
text-align="start"
flex=""
>
<span>Action 1</span>
</osds-button>
</osds-menu-item>
</osds-menu>`
}
},
{ title: "Firstname", field: "firstname", isSortable: true },
{ title: "Gender", field: "gender", isSortable: true },
{ title: "Date Of Birth", field: "dob", isSortable: true },
];
datagrid.rows = Array.from({ length: 5 }).fill({ name: "Garnbret", firstname: "Janja", gender: "female", dob: "12/03/1999" });
</script>
```
12 changes: 12 additions & 0 deletions packages/components/datagrid/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { getStencilJestConfig } from '@ovhcloud/ods-common-testing';

const config = getStencilJestConfig({
args: process.argv.slice(2),
options: {
moduleNameMapper: {
'tabulator-tables': '<rootDir>/src/jestStub.js',
}
}
});

export default config;
Loading

0 comments on commit 8156c4c

Please sign in to comment.