@kaiju.ui/components

2.5.3 • Public • Published

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

option type description default required
request json method и params grid-метода - yes
rowCallback function функция возвращающая id строчки на click false No
autoRefresh integer включает обновление данных каждые n секунд "Количество" No
ActionsComponent component компонент правой ячейки записи: удаление, редактирование и тд "Количество" No
labelCount string лейбл счетчика около пагинации "Количество" No
disableCount bool убрать счетчик около пагинации false No
disablePagination bool убрать пагинацию false No
checkable bool включает режим чекбоксов false No
checkCallback bool колбек на false No
accordion bool разделение таблицы на группы false No
cellConstructors json # TODO: false No
fieldConstructors json # TODO: false No

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

option type description default required
onClick or callback function the width of the carousel container. undefined Yes
icon string icon near the button none No
label string label of button none No
className string custom css class. none No
children components inner components - No
disabled bool disable button clicks while requests false No
style css json add custom style - No

Complex button options

Options of parameter 'conf':

option type description default required
mainButtonConf json of Button config simple button conf - Yes
dropDownConfs or items array of button confs [{label: ..., callback: ...} none No

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':

option type description default required
dropdownConf or doubleButtonConf or buttonConf button conf json версия кнопки справа вверху - No
settings callback click function иконка настройки - No
label string лейбл - No
searchCallback or searchConf function or search conf настройки поиска или функция на получение и обработку нового query - No
breadcrumbs breadcrumbs conf хлебные крошки - No
className string custom 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

option type description default required
isChanged bool показывает надпись "есть несохраненные изменения" - No
isFetching bool блокирует кнопки - 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

option type description default required
title string - no
message string text message настройки - no
delay integer time delay error - 3000, success - 1000 msec no
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.

option type description default required
defaultIndex integer номер какой вкладки показывать по-умолчанию 0 no
onSelect function получить новый индекс и сохранить его куда-нибудь - 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})

Readme

Keywords

none

Package Sidebar

Install

npm i @kaiju.ui/components

Weekly Downloads

26

Version

2.5.3

License

ISC

Unpacked Size

342 kB

Total Files

99

Last publish

Collaborators

  • poplavskiy-a
  • beastrock
  • xmachin
  • mishdrob
  • dardivil