2.5.2 • Published 7 months ago

@kaiju.ui/components v2.5.2

Weekly downloads
1
License
ISC
Repository
gitlab
Last release
7 months ago

README

Core package of kaiju.components;

Components list (docs checklist)

  • Table (DONE)
  • Header (DONE)
  • Buttons (DONE)
  • Notifications (DONE)
  • SearchComponent and SearchBox (DONE)
  • Select\MultiSelect Component
  • Tabs (DONE)
  • WindowActionComponent
  • Checkbox and Radio
  • Modals
  • BaseStorage (DONE)

Table

Options

optiontypedescriptiondefaultrequired
requestjsonmethod и params grid-метода-yes
rowCallbackfunctionфункция возвращающая id строчки на clickfalseNo
autoRefreshintegerвключает обновление данных каждые n секунд"Количество"No
ActionsComponentcomponentкомпонент правой ячейки записи: удаление, редактирование и тд"Количество"No
labelCountstringлейбл счетчика около пагинации"Количество"No
disableCountboolубрать счетчик около пагинацииfalseNo
disablePaginationboolубрать пагинациюfalseNo
checkableboolвключает режим чекбоксовfalseNo
checkCallbackboolколбек наfalseNo
accordionboolразделение таблицы на группыfalseNo
cellConstructorsjson# TODO:falseNo
fieldConstructorsjson# TODO:falseNo

Methods and stores

TODO: count, checkedIds, rowStore, all actions

tableStore.actions.isFetching - идёт ли запрос на бек в текущий момент времени this.props.tableStore.actions.fetchByPage() - получить страницу. Можно передать номер страницы, по-умолчанию получает первую.

Usage

import React from "react";
import TableComponent from "@kaiju.ui/components/src/Tables/TableComponent";
import {Provider} from "mobx-react";
import {TableStore} from "@kaiju.ui/components/src/Tables/stores";


class SomeComp extends React.Component {
    constructor(props) {
        super(props)

        this.tableStore = new TableStore({
            request: {
                method: "Product.grid", // метод отвечающий за построение таблицы
                params: { // параметры
                    engine: this.engineId,
                }
            },
            rowCallback: (rowStore) => {
                this.props.routerStore.router.navigate(ROUTES.invoiceEdit, {id: rowStore.id})
            }
        });
    }

    render() {
        return (
            <Provider tableStore={this.tableStore}>
                <TableComponent/>
            </Provider>
        )
    }
}

Пример с table actions component:

import {TableStore} from "@kaiju.ui/components/src/Tables/stores";
import TableComponent from "Tables/TableComponent";
import React from "react";
import {Provider} from "mobx-react";
import ROUTES from "smtg"
import ActionsComponent, {DeleteAction} from "@kaiju.ui/components/src/Tables/actions";


@inject("routerStore")
@inject("userStore")
class TableActionsComponent extends React.Component {

    delete() {
        Axios.post(ROUTES.rpc,
            {
                "method": `${this.props.serviceName}.delete`,
                "params": {
                    engine: this.props.routerStore.route.params["engineId"],
                    key: this.props.rowStore.id,
                }
            }
        ).then(response => {
            if (response.data.result) {
                this.props.tableStore.actions.fetchByPage()

            } else {
                utils.handleNotifyExceptions(response)
            }
        }).catch(response => {
            this.isFetching = false;
            utils.handleNotifyExceptions(response)
        })
    }

    getLabel() {
        let {label = {}} = toJS(this.props.rowStore.row);
        return label.value || this.props.rowStore.id
    }

    render() {
        let showDelete = !this.props.rowStore.isSystem
            && !this.props.rowStore.isDefault
            && this.props.userStore.hasPerm("system");


        return (
            <ActionsComponent>
                {
                    showDelete && (
                        <DeleteAction
                            idLabel={this.getLabel()}
                            actionLabel={utils.getTranslation("Message.delete")}
                            deleteCallback={() => this.delete()}/>
                    )
                }
            </ActionsComponent>
        )
    }
}


class Page extends React.Component {
    constructor(props) {
        super(props);

        this.tableStore = new TableStore({
            labelCount: "Инвойсы", // лейбл около пагинации, по дефолту выводится "Количество: n"
            checkable: true, // включает функционал чекБоксов
            checkMulti: false, // можно ли зачекать много сразу или только один
            disableCount: true, // убрать отображение каунтера
            disablePagination: true, // убрать отображение пагинации
            autoRefresh: 5, // (секунды)  автообновление, 
            request: {
                // запрос грид с параметрами
                method: "RusInvoice.grid", 
                params: {},
                errorCallback: (responseData) => {

                }
            },
            // конструктор ячеек 
            cellConstructors: {
                error: flagCell
            },
            // конструктор филдов 
            fieldConstructors: {
                error_bit: flagCell
            },
            // callback на чек
            checkCallback: (ids) => {
                console.log(ids)
            },
            // callback на клик по строчке таблицы
            rowCallback: (rowStore) => {
                this.props.routerStore.router.navigate(ROUTES.rusInvoiceEdit, {id: rowStore.id})
            },
            ActionsComponent: TableActionsComponent // компонент действий
        });
    }

    render() {
        return (
            <Provider tableStore={this.tableStore}>
                <TableComponent/>
            </Provider>
        )
    }
}

SearchComponents

import SearchComponent, {SearchBox} from "@kaiju.ui/components/src/SearchComponent"

this.searchConf = {
    suggestionConf: {
        key: "q",
        request: {
            method: "Query.suggest",
            params: {
                business_unit: this.pageStore.mainFilters.business_unit || null,
            }
        },
        Component: Suggestions
    },
    disabled: this.pageStore.isFetching,
    callback: (query) => {
        this.pageStore.onQueryChange(query)
    }
};

<SearchComponent {...this.searchConf}/>

<SearchBox
    placeholder: "Поиск по идентификатору"
    callback={query => console.log("query", query)/>

Buttons

Simple button components:

  • Button - simple button
  • ButtonSuccess - success-style button
  • ButtonDefault - default-style button

More complex buttons:

  • ButtonDropdown
  • DoubleButtonDropdown

Simple button options

optiontypedescriptiondefaultrequired
onClick or callbackfunctionthe width of the carousel container.undefinedYes
iconstringicon near the buttonnoneNo
labelstringlabel of buttonnoneNo
classNamestringcustom css class.noneNo
childrencomponentsinner components-No
disabledbooldisable button clicks while requestsfalseNo
stylecss jsonadd custom style-No

Complex button options

Options of parameter 'conf':

optiontypedescriptiondefaultrequired
mainButtonConfjson of Button configsimple button conf-Yes
dropDownConfs or itemsarray of button confs[{label: ..., callback: ...}noneNo

Example

import React from "react";
import ROUTES from "RoutingNames";

import {
Button,
ButtonSuccess,
ButtonDefault, 
ButtonDropdown, 
DoubleButtonDropdown 
} from "@kaiju.ui/components/src/Buttons";

class ExampleComp extends React.Component {

    constructor(props) {
        super(props);

        this.buttonConf = {
            label: utils.getTranslation("Button.create"),
            icon: "icon-plus",
            onClick: () => {
                this.props.routerStore.navigate(ROUTES.declarationAdd);
            }
        };
    }

    render() {
        return (
            <React.Fragment>
                // just point props directly into components
                <ButtonSuccess
                    label={"Открыть отчет"}
                    onClick={() => this.openReport()}
                />
                // all props from conf
                <ButtonDefault {...this.buttonConf}/>
            </React.Fragment>
        )
    }
}

class ExampleCompComplexBtns extends React.Component {

    constructor(props) {
        super(props);

        this.buttonDropdownConf = {
            mainButtonConf: {
                label: "Сохранить",
                // diff between dropdown conf and double button dropdown:
                // in double button you can path onclick event
                onClick: () => {
                    this.declarationStore.save();
                }
            },
            dropDownConfs: [
                {
                    label: "Report #1",
                    callback: () => this.openReport()
                },
                {
                    label: "Report #2",
                    callback: () => {
                        this.showDeleteWindow = true
                    }
                },
            ]
        };

        this.dropDownConf = {
            mainButtonConf: {
                label: "Настройки", // only label 
            },
            items: [
                {
                    label: "Report #1",
                    callback: () => {
                        console.log("test")
                    }
                },
                {
                    label: "Report #2",
                    callback: () => {
                        console.log("test")
                    }
                },
            ]
        };

    }

    render() {
        return (
            <React.Fragment>
                <ButtonDropdown conf={this.buttonDropdownConf}/>
                <DoubleButtonDropdown conf={...this.dropDownConf}/>
            </React.Fragment>
        )
    }
}

Header

Хедер на странице

Options

options of parameter 'conf':

optiontypedescriptiondefaultrequired
dropdownConf or doubleButtonConf or buttonConfbutton conf jsonверсия кнопки справа вверху-No
settingscallback click functionиконка настройки-No
labelstringлейбл-No
searchCallback or searchConffunction or search confнастройки поиска или функция на получение и обработку нового query-No
breadcrumbsbreadcrumbs confхлебные крошки-No
classNamestringcustom className-No

Пример:

import Header from "@kaiju.ui/components/src/Header/base";

// с лейблом:
<Header
    breadcrumbs={this.breadcrumbs}
    className={"test-class-name"}
    label={"Грузы"}
/>

// c  поисковой строкой:
<Header
    breadcrumbs={breadcrumbs}
    buttonConf={buttonConf}
    searchConf={searchConf}
/>

Формат хлебных крошек:

this.breadcrumbs = [
    {
        label: "Page #1",
        path: "Link to page for router5js"
    },
    {
        label: "Page #2",
    },
];

Dynamic Header

Тот же хедер, но способный с помощью mobx изменять своё состояние

Options

optiontypedescriptiondefaultrequired
isChangedboolпоказывает надпись "есть несохраненные изменения"-No
isFetchingboolблокирует кнопки-No

example:

import {observer} from "mobx-react";
import ROUTES from "RoutingNames";
import DynamicHeader from "@kaiju.ui/components/src/Header";

DynamicHeader = observer(() => {
    this.breadcrumbs = [
        {
            label: "Декларации таможни",
            path: ROUTES.declarationAll
        },
        {
            label: "Редактирование",
        },
    ];

    let {mainFormStore, invoicesFormStore} = this.declarationStore;

    return (
        <DynamicHeader
            breadcrumbs={this.breadcrumbs}
            doubleButtonConf={this.buttonDropdownConf}
            isChanged={mainFormStore.isChanged || invoicesFormStore.isChanged}
            isFetching={mainFormStore.isFetching || invoicesFormStore.isFetching}
            label={mainFormStore.label}
        />
    )
});

Notifications

Notify alert in the right bottom of the screen:

  • notifyError - red error alert
  • notifySuccess - green success alert

Options

optiontypedescriptiondefaultrequired
titlestring-no
messagestringtext message настройки-no
delayintegertime delayerror - 3000, success - 1000 msecno
import {notifyError, notifySuccess} from "@kaiju.ui/components/src/notifications";


notifyError("error", undefined, 300)
notifyError(null, "some message", 300)
notifySuccess("Done")

Tabs

Lib docs link --> ReactTabs

Main options

Все эти опции используются для того, чтобы сохранить состояне в session storage.

optiontypedescriptiondefaultrequired
defaultIndexintegerномер какой вкладки показывать по-умолчанию0no
onSelectfunctionполучить новый индекс и сохранить его куда-нибудь-no

Examples

Simple example:

import React from "react";
import {Tab, TabList, TabPanel, Tabs} from "@kaiju.ui/components/src/Tabs";
import Form from "@kaiju.ui/forms/src/Form";

export default class AttributeAddPage extends React.Component {

    render() {
        let {formStore} = this.formHandleStore;

        return (
            <React.Fragment>

                <Tabs className="page-content-body pl-5 pr-5"
                      defaultIndex={BaseStorage.getItem(this.props.route.name, 0)}
                      onSelect={(index) => BaseStorage.setItem(this.props.route.name, index)}>
                    <TabList>
                        <Tab>{utils.getTranslation("Tab.properties")}</Tab>
                    </TabList>

                    <TabPanel>
                        {
                            this.formHandleStore.dataInitialized &&
                            <div className={this.formHandleStore.isFetching ? "disabled-form mt-5" : " mt-5"}>
                                <Form key={formStore.key}
                                      store={formStore}
                                      groupFiltering/>
                            </div>
                        }
                    </TabPanel>

                </Tabs>
            </React.Fragment>
        )
    }
}

Dynamicly add tab:

import React from "react";
import ROUTES from "RoutingNames";
import {Tab, TabList, TabPanel, Tabs} from "@kaiju.ui/components/src/Tabs";
import Form from "@kaiju.ui/forms/src/Form";
import {observer} from "mobx-react";
import {observable} from "mobx";
import Axios from "axios";

@observer
export default class AttributeEditPage extends React.Component {
    @observable has_options = false;

    constructor(props) {
        super(props);
        // pass
    }

    componentDidMount() {
        this.checkIfOptionsEnabled()
    }

    checkIfOptionsEnabled() {
        // make request 
        Axios.post(ROUTES.rpc,
            {
                method: `${this.serviceName}.get`,
                params: {
                    engine: this.engineId,
                    key: this.attributeKey,
                    grouping: false
                }
            }
        ).then(response => {
            let result = response.data.result;

            // if attr has option mobX will rerender Tabs
            if (result) {
                this.has_options = result.kind === 'string'
            } else {
                utils.handleNotifyExceptions(response)
            }
        }).catch(response => {
            utils.handleNotifyExceptions(response)
        })
    };

    renderOptionsTable() {
        // pass
    }

    render() {
        let {formStore} = this.formHandleStore;


        const tabs = [
            <Tab key={utils.uuid4()}>{utils.getTranslation("Tab.properties")}</Tab>

        ];
        const tabPanels = [
            <TabPanel key={utils.uuid4()}>
                {
                    this.formHandleStore.dataInitialized &&
                    <div className={this.formHandleStore.isFetching ? "disabled-form mt-5" : " mt-5"}>
                        <Form key={formStore.key}
                              store={formStore}
                              groupFiltering/>
                    </div>
                }
            </TabPanel>
        ];

        if (this.has_options) {
            tabs.push(<Tab key={utils.uuid4()}>{utils.getTranslation("Label.options")}</Tab>);
            tabPanels.push(<TabPanel key={utils.uuid4()}>{this.renderOptionsTable()}</TabPanel>)
        }

        return (
            <React.Fragment>
                <Tabs className="attr-tabs__content_body pl-5 pr-5">
                    <TabList>{tabs}</TabList>
                    {tabPanels}
                </Tabs>
            </React.Fragment>
        )
    }
}

BaseStorage

Обертка от sessionStorage, чтобы хранить данные пользователя при сессии

BaseStorage.getItem("key")
BaseStorage.setItem("key", "some_value")
BaseStorage.setItem("key", {"count": 1})
2.5.0

10 months ago

2.5.2

7 months ago

2.5.1

8 months ago

2.4.7

1 year ago

2.4.6

1 year ago

2.4.9

1 year ago

2.4.8

1 year ago

2.4.1

1 year ago

2.4.0

1 year ago

2.4.3

1 year ago

2.4.5

1 year ago

2.4.4

1 year ago

2.3.6

2 years ago

2.3.8

2 years ago

2.3.7

2 years ago

2.3.9

2 years ago

2.3.3

2 years ago

2.3.5

2 years ago

2.2.7

2 years ago

2.2.6

2 years ago

2.2.9

2 years ago

2.2.8

2 years ago

2.2.5

2 years ago

2.2.3

2 years ago

2.2.4

2 years ago

2.2.2

3 years ago

2.2.1

3 years ago

2.1.9

3 years ago

2.1.6

3 years ago

2.1.5

3 years ago

2.1.8

3 years ago

2.1.7

3 years ago

2.0.10

3 years ago

2.1.2

3 years ago

2.1.1

3 years ago

2.1.4

3 years ago

2.1.3

3 years ago

2.1.0

3 years ago

2.0.9

3 years ago

2.0.8

3 years ago

2.0.3

3 years ago

2.0.2

3 years ago

2.0.5

3 years ago

2.0.4

3 years ago

2.0.7

3 years ago

2.0.6

3 years ago

2.0.1

3 years ago

2.0.0

3 years ago

1.9.9

3 years ago

1.9.8

3 years ago

1.9.7

3 years ago

1.9.6

3 years ago

1.9.5

3 years ago

1.9.4

3 years ago

1.9.3

3 years ago

1.9.1

3 years ago

1.9.0

3 years ago

1.9.2

3 years ago

1.8.9

3 years ago

1.8.7

3 years ago

1.8.8

3 years ago

1.8.6

3 years ago

1.8.5

3 years ago

1.8.4

3 years ago

1.8.2

3 years ago

1.8.3

3 years ago

1.8.1

3 years ago

1.8.0

3 years ago

1.7.9

3 years ago

1.7.8

3 years ago

1.7.7

3 years ago

1.7.6

3 years ago

1.7.5

3 years ago

1.7.4

3 years ago

1.7.3

3 years ago

1.7.2

3 years ago

1.7.1

3 years ago

1.7.0

3 years ago

1.6.9

3 years ago

1.6.8

3 years ago

1.6.7

3 years ago

1.6.6

3 years ago

1.6.4

3 years ago

1.6.5

3 years ago

1.6.2

3 years ago

1.6.1

3 years ago

1.6.0

3 years ago

1.5.9

3 years ago

1.5.8

3 years ago

1.5.7

3 years ago

1.5.6

3 years ago

1.5.5

3 years ago

1.5.4

3 years ago

1.5.3

3 years ago

1.5.2

3 years ago

1.5.1

3 years ago

1.4.9

3 years ago

1.4.8

3 years ago

1.4.6

3 years ago

1.4.5

3 years ago

1.4.4

3 years ago

1.4.7

3 years ago

1.4.3

3 years ago

1.4.2

4 years ago

1.4.1

4 years ago

1.4.0

4 years ago

1.3.9

4 years ago

1.3.8

4 years ago

1.3.7

4 years ago

1.3.6

4 years ago

1.3.5

4 years ago

1.3.4

4 years ago

1.3.3

4 years ago

1.3.2

4 years ago

1.3.1

4 years ago

1.3.0

4 years ago

1.2.9

4 years ago

1.2.8

4 years ago

1.2.7

4 years ago

1.2.6

4 years ago

1.2.5

4 years ago

1.2.4

4 years ago

1.2.3

4 years ago

1.2.2

4 years ago

1.2.1

4 years ago

1.2.0

4 years ago

1.1.9

4 years ago

1.1.8

4 years ago

1.1.7

4 years ago

1.1.6

4 years ago

1.1.5

4 years ago

1.1.4

4 years ago

1.1.3

4 years ago

1.1.2

4 years ago

1.1.1

4 years ago

1.1.0

4 years ago

1.0.9

4 years ago

1.0.8

4 years ago

1.0.7

4 years ago

1.0.6

4 years ago

1.0.5

4 years ago

1.0.4

4 years ago

1.0.3

4 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago

0.9.8

4 years ago

0.9.9

4 years ago

0.9.7

4 years ago

0.9.6

4 years ago

0.9.5

4 years ago

0.9.4

4 years ago

0.9.3

4 years ago

0.9.2

4 years ago

0.9.0

4 years ago

0.9.1

4 years ago

0.8.9

4 years ago

0.8.8

4 years ago

0.8.7

4 years ago

0.8.6

4 years ago

0.8.5

4 years ago

0.8.4

4 years ago

0.8.3

4 years ago

0.8.2

4 years ago

0.8.1

4 years ago

0.7.9

4 years ago

0.8.0

4 years ago

0.7.8

4 years ago

0.7.7

4 years ago

0.7.6

4 years ago

0.7.5

4 years ago

0.7.4

4 years ago

0.7.3

4 years ago

0.7.2

4 years ago

0.7.1

4 years ago

0.6.9

4 years ago

0.6.8

4 years ago

0.7.0

4 years ago

0.6.7

4 years ago

0.6.6

4 years ago

0.6.5

4 years ago

0.6.4

4 years ago

0.6.3

4 years ago

0.6.2

4 years ago

0.6.1

4 years ago

0.5.0

4 years ago

0.6.0

4 years ago

0.1.0

4 years ago

1.5.0

4 years ago