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/bootstrap v5 #431

Draft
wants to merge 24 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4b8e91a
dattable styles udpate
petrKavulok Jun 29, 2023
a80cce7
components styling updat
petrKavulok Jun 29, 2023
c7c237b
paddning and margin general styles udpate
petrKavulok Jun 29, 2023
6cfc54e
general padding/margin styles
petrKavulok Jul 17, 2023
c1659e7
general padding styles udpate
petrKavulok Jul 18, 2023
babbdf3
alerts bootstrap 5 refactorization
petrKavulok Jul 25, 2023
5038eff
bootstra v5 - components refactorization
petrKavulok Jul 25, 2023
a4790c1
containers bootstrap v5 refactorization
petrKavulok Jul 25, 2023
a5a0323
maintenantce module - bootstra v5 refactor
petrKavulok Jul 25, 2023
54ea90b
auth module - bootstrap v5 refactor
petrKavulok Jul 25, 2023
543ab51
bootstrap v5 refactor
petrKavulok Jul 25, 2023
a414fd2
demo - bootstrap v5 refactor
petrKavulok Jul 25, 2023
d44f4b6
link - text decoration removal
petrKavulok Jul 27, 2023
541e12c
dropdown appearance update
petrKavulok Jul 27, 2023
50bbc4e
bootstra v5 update
petrKavulok Jul 27, 2023
aab821d
indentaion fix
petrKavulok Jul 31, 2023
ab2e7fc
obsolete code removal
petrKavulok Jul 31, 2023
734aa10
Merge branch 'master' into feature/bootstrap-v5
petrKavulok Jul 31, 2023
ca86a01
bootstrap 5 migration update
petrKavulok Aug 3, 2023
6d0ee16
bbootstrap input group addon update
petrKavulok Aug 3, 2023
e70f026
confict resolution
petrKavulok Aug 3, 2023
8dad614
Merge branch 'master' into feature/bootstrap-v5
petrKavulok Aug 6, 2023
f2e7345
Fix conflicts & Merge branch 'master' into feature/bootstrap-v5
Pe5h4 Aug 8, 2023
043b945
Comment
Pe5h4 Aug 10, 2023
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
14 changes: 7 additions & 7 deletions demo/src/modules/home/containers/TableContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,12 @@ const initData = {
default:
break;
}

}
return { data: filteredData.slice((page-1)*limit, limit*page), count: filteredData.length };
},
headers: [
{
headers: [
{
name: 'Link',
key: 'username',
link: {
Expand All @@ -175,9 +175,9 @@ const initData = {
key: '_c',
datetime: { format: 'lll' }
},
{
name: 'Text',
key: '_provider_id'
{
name: 'Text',
key: '_provider_id'
},
{
name: 'Custom',
Expand Down Expand Up @@ -245,7 +245,7 @@ export default function (props) {
onClick() {alert("You've clicked button with authz")},
resource: "res:res",
resources: ["res:res"],
children: (<><i className="at-trash mr-2"></i>ButtonWithAuthz</>)
children: (<><i className="at-trash me-2"></i>ButtonWithAuthz</>)
}

const noItemsComponent = (
Expand Down
58 changes: 29 additions & 29 deletions doc/datatable/datatable.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# ASAB WebUI DataTable component

`DataTable` is react reusable component.
It is used to display common data like numbers and strings.
It is used to display common data like numbers and strings.

Also `DataTable` supports `advmode`. When `advmode` is enabled, `DataTable` displays extra column which is json for data passed in as `data` prop. More info about `advmode` can be found in `doc/advmode.md`.

Demo app's path: `asab-webui/demo/src/modules/home/containers/TableContainer.js`.

# Implementation

DataTable can be mounted in its own container as it is implemented in demo app or as a widget in another app's container. In first case you must create container for `DataTable` and connect it to any module of your application by adding it's route and navigation item.
DataTable can be mounted in its own container as it is implemented in demo app or as a widget in another app's container. In first case you must create container for `DataTable` and connect it to any module of your application by adding it's route and navigation item.

Example from demo:

Expand Down Expand Up @@ -66,7 +66,7 @@ let ConfigDefaults = {
headers: [
{ name: 'Name', key: 'username' },
{ name: 'Provider', key: '_provider_id' },
{ name: 'Type', key: '_type' }
{ name: 'Type', key: '_type' }
],
limit: 10
},
Expand All @@ -89,14 +89,14 @@ Prop `title` is an object that has obligatory property `text` which is string an
Example:

```js
headers: [
{
headers: [
{
name: 'Name',
key: 'username',
customHeaderStyle: { minWidth: '100px' },
customCellStyle: { textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
customCellStyle: { textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
maxWidth: "15ch"
}
},
Expand All @@ -121,7 +121,7 @@ title: {
}
```

Optional property `link` is either an object or a function.
Optional property `link` is either an object or a function.
Object contains properties `pathname` and `key`, where `pathname` is a string which is representing pathname for <Link> component and `key` is a key name for getting id for pathname.
Output for link cell would look like:

Expand All @@ -142,7 +142,7 @@ const headers = [
```


If `pathname` is "/user/", `key` is "_id" and data for that cell is
If `pathname` is "/user/", `key` is "_id" and data for that cell is
{
...
_id: 1,
Expand Down Expand Up @@ -213,7 +213,7 @@ headers: [
{ name: 'Actions', actionButton: {
title: 'Actions',
actions: [
{
{
name: "Action 1",
onClick(row, header) { alert(row._id); },
icon: "cib-jenkins"
Expand Down Expand Up @@ -258,9 +258,9 @@ function (props) {
const [data, setData] = useState([]);
const [page, setPage] = useState(1);
const [count, setCount] = useState(0);

...
const fetchData = (page) => {...}
const fetchData = (page) => {...}
...

useEffect(() => {
Expand Down Expand Up @@ -391,7 +391,7 @@ Example of `buttonWithAuthz`:
onClick() {alert("You've clicked button with authz")},
resource: "res:res",
resources: ["res:res"],
children: (<><i className="at-trash mr-2"></i>ButtonWithAuthz</>)
children: (<><i className="at-trash me-2"></i>ButtonWithAuthz</>)
}
...

Expand Down Expand Up @@ -482,9 +482,9 @@ function (props) {
const [page, setPage] = useState(1);
const [count, setCount] = useState(0);
const [str, setStr] = useState('');

...
const fetchData = (page, str="") => {...}
const fetchData = (page, str="") => {...}
...

useEffect(() => {
Expand Down Expand Up @@ -525,14 +525,14 @@ let ConfigDefaults = {
```

Prop `category` is an object which contains a key `sublistKey` for children object from list of data and `key` which will be taken to render td for target parent object. Also you can path some type prop like `link` or `customComponent` to generate cell component for parent.
`sublistKey` value of parent object also should an object with such structure:
`sublistKey` value of parent object also should an object with such structure:
```js
"children": {
"data": [...],
"count": 10
}
```
NOTE: If `sublistKey` is not present in target parent object then sublist for this object will not be generated
NOTE: If `sublistKey` is not present in target parent object then sublist for this object will not be generated

```js
const data = [
Expand Down Expand Up @@ -648,7 +648,7 @@ return (
)
```

Prop `noItemsComponent` is used if you want to define custom component or string for displaying message when number of items in data passed into `DataTable` is zero. As string just write message you want to display.
Prop `noItemsComponent` is used if you want to define custom component or string for displaying message when number of items in data passed into `DataTable` is zero. As string just write message you want to display.

Example of using `noItemsComponent` as string:
```js
Expand Down Expand Up @@ -743,10 +743,10 @@ Property `onDownload` of `customComponent` is needed if you want to use custom c
Property `height` is needed if you want the item of elements in the table to adjust to the height of the web page when it first loads.
NOTE: `height` should be used in conjunction with the `limit` and `setLimit`.
> You will need two `useEffect`:
>
> - The first will calculate the height of the container when it is first loaded.
>
> - The first will calculate the height of the container when it is first loaded.
> - The second you need to have the number of rows displayed dynamically, you need to add a condition (`limit > 0`), where you call the function that gets the data for the table. It will be in the same `useEffect` in which you called the function before.
>
>
You also need to add `useRef`. You will need to place it on the wrapper tag. It can only be `<div>`.Be sure to style this tag to 100% height.
The number of items displayed per page will be a multiple of 5.
```js
Expand Down Expand Up @@ -826,21 +826,21 @@ props: {
setPage: function, // function for setting page number
title: {
text: string, // name of a table
icon?: string | React.Component // Icon that will be displayed alongside the text as component or
// as <i className={icon}></i> in case icon is string.
},
icon?: string | React.Component // Icon that will be displayed alongside the text as component or
// as <i className={icon}></i> in case icon is string.
},
limit?: number, // limit of items per page. Default is 10
setLimit?: function, // function for setting limit
height?: number, // table height
createButton?: {
text: string, // text inside button
pathname: string, // URL for redirecting to create page
icon?: string|React.component, // Icon that will be displayed alongside the text as component or
// as <i className={icon}></i> in case icon is string.
icon?: string|React.component, // Icon that will be displayed alongside the text as component or
// as <i className={icon}></i> in case icon is string.
},
search?: boolean | {
placeholder?: string, // placeholder for search input box
icon?: string | React.Component // Icon that will be displayed alongside the text as component or
icon?: string | React.Component // Icon that will be displayed alongside the text as component or
// as <i className={icon}></i> in case icon is string.
},
onSearch?: function, // function that is called in 500ms after changes has been made in search input box
Expand All @@ -849,4 +849,4 @@ props: {
noItemsComponent?: string | React.component // custom component for displaying message when there are no items
}

```
```
6 changes: 3 additions & 3 deletions src/components/Credentials.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function Credentials({ ...props }) {
credentials.map((credentialObj) => {
return (
<div title={credentialObj.id}>
<i className="at-account pr-1"></i>
<i className="at-account pe-1"></i>
<Link {...props} to={{ pathname: `/auth/credentials/${credentialObj.id}` }}>
{credentialObj.username}
</Link>
Expand All @@ -71,7 +71,7 @@ export function Credentials({ ...props }) {
credentials_ids.map((credentials_id) => {
return (
<div>
<i className="at-account pr-1"></i>
<i className="at-account pe-1"></i>
<Link {...props} to={{ pathname: `/auth/credentials/${credentials_id}` }}>
{credentials_id}
</Link>
Expand Down Expand Up @@ -123,4 +123,4 @@ function saveUsernamesToLS(data, credentials_ids, cleanupTime) {
localStorage.setItem('Credentials', JSON.stringify(dataInLS));
return dataToLS;
}
}
}
10 changes: 5 additions & 5 deletions src/components/DataTable/ActionButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap

const ActionButton = ({ actionButton, row, header }) => {
const [isOpen, setOpen] = useState(false);

return (
<Dropdown
className="action-button-dropdown float-right mr-2"
className="action-button-dropdown float-end me-2"
isOpen={isOpen}
toggle={() => setOpen(prev => !prev)}
size="sm"
>
<DropdownToggle
<DropdownToggle
className="action-button-dropdown-toggle text-primary"
tag="span"
style={{ textDecoration: "none", cursor: "pointer" }}
Expand All @@ -22,7 +22,7 @@ const ActionButton = ({ actionButton, row, header }) => {
<DropdownMenu>
{actionButton.title && (
<DropdownItem
header
header
className="action-button-dropdown-header"
>
<span style={{ fontWeight: 700 }}>{actionButton.title}</span>
Expand All @@ -39,7 +39,7 @@ const ActionButton = ({ actionButton, row, header }) => {
</DropdownItem>
))}
</DropdownMenu>

</Dropdown>
)
}
Expand Down
24 changes: 12 additions & 12 deletions src/components/DataTable/Buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import {
export const CreateButton = ({ createButton }) => {

return (
<div className="float-right ml-3 data-table-create-button">
<div className="float-end ms-3 data-table-create-button">
<Link to={{ pathname: createButton.pathname }}>
<Button tag="span">
{createButton.icon &&
<span className="pr-1">
{createButton.icon &&
<span className="pe-1">
{typeof createButton.icon === 'string' ? <i className={createButton.icon}></i> : createButton.icon}
</span>
}
Expand All @@ -27,7 +27,7 @@ export const DownloadButton = ({ onDownload, headers, title }) => {

const downloadHandler = () => {
const list = onDownload();
let csv = headers.map(header => header.name).join(',') + "\n" +
let csv = headers.map(header => header.name).join(',') + "\n" +
list.map(item => headers.map(header => {
if (header.customComponent) {
if (header.customComponent.onDownload)
Expand All @@ -42,7 +42,7 @@ export const DownloadButton = ({ onDownload, headers, title }) => {
}

return (
<div className="float-right ml-3 data-table-download-button">
<div className="float-end ms-3 data-table-download-button">
<Button tag="span" onClick={downloadHandler} >
<i className="at-arrow-down"></i>
Download
Expand All @@ -53,15 +53,15 @@ export const DownloadButton = ({ onDownload, headers, title }) => {

export const ActionButton = ({ actionButton, row, header }) => {
const [isOpen, setOpen] = useState(false);

return (
<Dropdown
className="action-button-dropdown float-right mr-2"
className="action-button-dropdown float-end me-2"
isOpen={isOpen}
toggle={() => setOpen(prev => !prev)}
size="sm"
>
<DropdownToggle
<DropdownToggle
className="action-button-dropdown-toggle text-primary"
tag="span"
style={{ textDecoration: "none", cursor: "pointer" }}
Expand All @@ -71,7 +71,7 @@ export const ActionButton = ({ actionButton, row, header }) => {
<DropdownMenu>
{actionButton.title && (
<DropdownItem
header
header
className="action-button-dropdown-header"
>
<span style={{ fontWeight: 700 }}>{actionButton.title}</span>
Expand Down Expand Up @@ -100,9 +100,9 @@ export const CustomButton = ({ customButton }) => {
tag="span"
{...customButton?.props}
>
{customButton.icon &&
<span className="pr-1">
{typeof customButton.icon === 'string' ?
{customButton.icon &&
<span className="pe-1">
{typeof customButton.icon === 'string' ?
<i className={customButton.icon}></i> : customButton.icon
}
</span>
Expand Down
6 changes: 2 additions & 4 deletions src/components/DataTable/Search.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import React from 'react';

import {
InputGroup, InputGroupText, Input, InputGroupAddon
InputGroup, InputGroupText, Input
} from 'reactstrap';

const Search = ({ search, filterValue, setFilterValue }) => {

return (
<div className="float-right ml-3 data-table-search">
<div className="float-end ms-3 data-table-search">
<InputGroup>
{search.icon &&
<InputGroupAddon addonType="prepend">
<InputGroupText><i className={search.icon}></i></InputGroupText>
</InputGroupAddon>
}
<Input
value={filterValue}
Expand Down
6 changes: 3 additions & 3 deletions src/components/DataTable/Sort.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ const Sort = ({ sort }) => {
const [isSortOpen, setSortDropdown] = useState(false);

return (
<div className="float-right ml-3 data-table-sort">
<div className="float-end ms-3 data-table-sort">
<Dropdown
isOpen={isSortOpen}
toggle={() => setSortDropdown(prev => !prev)}
>
<DropdownToggle caret>
{sort.icon && <i className={`${sort.icon} mr-1`}></i>}
{sort.icon && <i className={`${sort.icon} me-1`}></i>}
{sort.title}
</DropdownToggle>
<DropdownMenu>
{sort.items.map((item, idx) => (
<DropdownItem onClick={() => sort.onClick(item.value)} key={idx}>
{item.icon && <i className={`${item.icon} mr-1`}></i>}
{item.icon && <i className={`${item.icon} me-1`}></i>}
{item.name}
</DropdownItem>
))
Expand Down
Loading