diff --git a/README.md b/README.md index 1ac37a5..347ca20 100644 --- a/README.md +++ b/README.md @@ -1390,6 +1390,10 @@ const MyPanel = () => { `groups` - необязательный, массив групп данных, содержит объекты вида `{name: <ИМЯ_ГРУППЫ>, caption: <ЗАГОЛОВОК_ГРУППЫ>, expandable: <ПРИЗНАК_РАЗВОРАЧИВАЕМОСТИ_ГРУППЫ - true|false>, expanded: <ПРИЗНАК_РАЗВЕРНУТОСТИ_ГРУППЫ - true|false>}`\ `rows` - необязательный, массив, отображаемые таблицой строки данных, содержит объекты вида `{groupName: <ИМЯ_ГРУППЫ_СОДЕРЖАЩЕЙ_СТРОКУ>, <ИМЯ_КОЛОНКИ>: <ЗНАЧЕНИЕ>}`\ `size` - необязательный, строка, размер отступов при вёрстке таблицы, `small|medium` (см. константу `P8P_DATA_GRID_SIZE` в исходном коде компонента)\ +`pageNumber` - необязательный, число, номер отображаемой страницы таблицы, по умолчанию - 1\ +`pagesCount` - необязательный, число, количество страниц таблицы, по умолчанию - 0. При значении > 0, параметр `morePages` игнорируется, а у таблицы появляется область отображения страниц (исходя из параметров `pagesAlign` и `pagesPosition`)\ +`pagesAlign` - необязательный, строка, размещение области страниц по вертикали, по умолчанию `right`, поддерживает значения `left|right|center` (см. константу `P8P_DATA_GRID_PAGINATOR_ALIGN` в исходном коде компонента)\ +`pagesPosition` - необязательный, строка, размещение области страниц по горизонтали, по умолчанию `bottom`, поддерживает значения `top|bottom|both` (см. константу `P8P_DATA_GRID_PAGINATOR_POSITION` в исходном коде компонента)\ `fixedHeader` - необязательный, логический, признак фиксации заголовка таблицы, по умолчанию - `false`\ `fixedColumns` - необязательный, число, количество фиксированных колонок слева, по умолчанию - 0\ `morePages` - необязательный, логический, признак отображения кнопки догрузки данных, по умолчанию - `false`\ @@ -1417,6 +1421,7 @@ const MyPanel = () => { `onOrderChanged` - необязательный, функция, будет вызвана при изменении пользователем состояния сортировок таблицы. Сигнатура функции `f({orders})`, результат функции не интерпретируется. В функцию передаётся объект, поле `orders` которого, содержит текущее состояние сортировок таблицы. Объект `orders` - массив, содержащий элементы вида `{name: <НАИМЕНОВАНИЕ_КОЛОНКИ>, direction: }`. Функция применяется для инициации обновления данных в таблице.\ `onFilterChanged` - необязательный, функция, будет вызвана при изменении пользователем состояния фильтров таблицы. Сигнатура функции `f({filters})`, результат функции не интерпретируется. В функцию передаётся объект, поле `filters` которого, содержит текущее состояние фильтров таблицы. Объект `filters` - массив, содержащий элементы вида `{name: <НАИМЕНОВАНИЕ_КОЛОНКИ>, from: <ЗНАЧЕНИЕ_НАЧАЛА_ДИАПАЗОНА_ОТБОРА>, to: <ЗНАЧЕНИЕ_ОКОНЧАНИЯ_ДИАПАЗОНА_ОТБОРА>}`. Функция применяется для инициации обновления данных в таблице.\ `onPagesCountChanged` - необязательный, функция, будет вызвана при изменении пользователем количества отображаемых страниц данных таблицы. Сигнатура функции `f()`, результат функции не интерпретируется. Функция применяется для инициации обновления данных в таблице.\ +`onPageChanged` - необязательный, функция, будет вызвана при изменении пользователем страницы в области отображения страниц (при `pagesCount` > 0). Сигнатура функции `f({page})`, результат функции не интерпретируется. В функцию передается объект, поле `page` которого, содержит номер выбранной страницы. Значение `page` - число. Функция применяется для инициации обновления данных в таблице. `objectsCopier` - обязательный, функция глубокого копирования объектов (применяется при обслуживании собственного состояния таблицы данных). Сигнатура функции `f(Object)`, должна возвращать глубокую копию объекта. Некоторые параметры таблицы данных вынесены в свойства компонента `P8PDataGrid` для минимизации его связи с фреймворком и поддержания возможности стороннего использования (например, свойства `orderAscMenuItemCaption`, `okFilterBtnCaption`, `objectsCopier` и т.п.) . Тем не менее, в настройках фреймворка и его окружении уже есть реализации для данных свойств. Например, в "app.text.js" уже содержатся объявления типовых констант для текстов подписей кнопок и пунктов меню, в "app/core/utils.js" реализована элементарная функция глубокого копиования `deepCopyObject`. Поэтому, в "app/config_wrapper.js" для привязки свойств `P8PDataGrid` к контексту фреймворка реализованы специальные декораторы и объекты-шаблоны, облегчающие подключение экземпляра `P8PDataGrid` к панели и снимающие с разработчика необходимость указывать некоторые из перечисленных выше обязательных свойств. В предложенном ниже примере, из модуля "config_wrapper" в панель импортируется объект `P8P_DATA_GRID_CONFIG_PROPS`, который уже содержт преднастроенное описание свойств `orderAscMenuItemCaption`, `orderDescMenuItemCaption`, `filterMenuItemCaption`, `valueFilterCaption`, `valueFromFilterCaption`, `valueToFilterCaption`, `okFilterBtnCaption`, `clearFilterBtnCaption`, `cancelFilterBtnCaption`, `morePagesBtnCaption`, `noDataFoundText` и `objectsCopier`, полученное из окружения фреймворка. Таким образом, прикладной разработчик может не указывать их значения при использовании `P8PDataGrid` (если по каким-то причинам не хочет их переопределить, конечно). @@ -1440,6 +1445,7 @@ const MyPanel = () => { Для таблицы данных это (см. детальные описания программных интерфейсов в пакете `PKG_P8PANELS_VISUAL`): `PKG_P8PANELS_VISUAL.TDG_MAKE` - функция, инициализация таблицы данных, возвращает объект для хранения описания таблицы\ +`PKG_P8PANELS_VISUAL.TDG_PAGES_COUNT_SET` - процедура, служит для обновления значения количества отображаемых страниц\ `PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF` - процедура, добавление описания колонки в таблицу, принимает на вход объект с описанием таблицы и параметры, описывающие добавляемую колонку (её имя, заголовок, тип данных, видимость, доступность отбора и сортировки, набор предопределённых значений и т.д.)\ `PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD` - процедура, служит для формирования коллекции предопределённых значений колонки таблицы (подготовленная коллекция передаётся в `RCOL_VALS` вызова `TDG_ADD_COL_DEF`, если необходимо)\ `PKG_P8PANELS_VISUAL.TDG_ADD_GROUP` - процедура, служит для добавления описания группы в таблицу данных, на вход принимает объект для хранения описания таблицы и параметры добавляемой группы\ diff --git a/app/components/p8p_data_grid.js b/app/components/p8p_data_grid.js index 56dcf31..5c6266e 100644 --- a/app/components/p8p_data_grid.js +++ b/app/components/p8p_data_grid.js @@ -9,7 +9,16 @@ import React, { useState, useEffect } from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента -import { P8PTable, P8P_TABLE_SIZE, P8P_TABLE_DATA_TYPE, P8P_TABLE_FILTER_SHAPE, P8P_TABLE_MORE_HEIGHT, P8P_TABLE_FILTERS_HEIGHT } from "./p8p_table"; //Таблица +import { + P8PTable, + P8P_TABLE_SIZE, + P8P_TABLE_DATA_TYPE, + P8P_TABLE_FILTER_SHAPE, + P8P_TABLE_MORE_HEIGHT, + P8P_TABLE_FILTERS_HEIGHT, + P8P_TABLE_PAGINATOR_ALIGN, + P8P_TABLE_PAGINATOR_POSITION +} from "./p8p_table"; //Таблица //--------- //Константы @@ -30,6 +39,12 @@ const P8P_DATA_GRID_MORE_HEIGHT = P8P_TABLE_MORE_HEIGHT; //Высота фильтров таблицы const P8P_DATA_GRID_FILTERS_HEIGHT = P8P_TABLE_FILTERS_HEIGHT; +//Размещение области страниц по вертикали +const P8P_DATA_GRID_PAGINATOR_ALIGN = P8P_TABLE_PAGINATOR_ALIGN; + +//Размещение области страниц по горизонтали +const P8P_DATA_GRID_PAGINATOR_POSITION = P8P_TABLE_PAGINATOR_POSITION; + //----------- //Тело модуля //----------- @@ -43,6 +58,10 @@ const P8PDataGrid = ({ groups = [], rows = [], size, + pageNumber = 1, + pagesCount = 0, + pagesAlign = P8P_DATA_GRID_PAGINATOR_ALIGN.RIGHT, + pagesPosition = P8P_DATA_GRID_PAGINATOR_POSITION.BOTTOM, fixedHeader = false, fixedColumns = 0, morePages = false, @@ -70,6 +89,7 @@ const P8PDataGrid = ({ onOrderChanged, onFilterChanged, onPagesCountChanged, + onPageChanged, objectsCopier }) => { //Собственное состояние - сортировки @@ -108,6 +128,9 @@ const P8PDataGrid = ({ if (onPagesCountChanged) onPagesCountChanged(); }; + //При изменении номера страницы + const handlePageChange = ({ page }) => onPageChanged && onPageChanged({ page }); + //При изменении списка установленных извне фильтров useEffect(() => { setFilters(filtersInitial || []); @@ -124,6 +147,10 @@ const P8PDataGrid = ({ orders={orders} filters={filters} size={size || P8P_DATA_GRID_SIZE.MEDIUM} + pageNumber={pageNumber} + pagesCount={pagesCount} + pagesAlign={pagesAlign} + pagesPosition={pagesPosition} fixedHeader={fixedHeader} fixedColumns={fixedColumns} morePages={morePages} @@ -152,6 +179,7 @@ const P8PDataGrid = ({ onOrderChanged={handleOrderChanged} onFilterChanged={handleFilterChanged} onPagesCountChanged={handlePagesCountChanged} + onPageChanged={handlePageChange} /> ); }; @@ -165,6 +193,10 @@ P8PDataGrid.propTypes = { groups: PropTypes.array, rows: PropTypes.array, size: PropTypes.string, + pageNumber: PropTypes.number, + pagesCount: PropTypes.number, + pagesAlign: PropTypes.string, + pagesPosition: PropTypes.string, fixedHeader: PropTypes.bool, fixedColumns: PropTypes.number, morePages: PropTypes.bool, @@ -192,6 +224,7 @@ P8PDataGrid.propTypes = { onOrderChanged: PropTypes.func, onFilterChanged: PropTypes.func, onPagesCountChanged: PropTypes.func, + onPageChanged: PropTypes.func, objectsCopier: PropTypes.func.isRequired }; @@ -205,5 +238,7 @@ export { P8P_DATA_GRID_FILTER_SHAPE, P8P_DATA_GRID_MORE_HEIGHT, P8P_DATA_GRID_FILTERS_HEIGHT, + P8P_DATA_GRID_PAGINATOR_ALIGN, + P8P_DATA_GRID_PAGINATOR_POSITION, P8PDataGrid }; diff --git a/app/components/p8p_table.js b/app/components/p8p_table.js index dce4693..363d51c 100644 --- a/app/components/p8p_table.js +++ b/app/components/p8p_table.js @@ -16,6 +16,7 @@ import { TableContainer, TableHead, TableRow, + Pagination, Paper, IconButton, Icon, @@ -81,6 +82,20 @@ const P8P_TABLE_FILTER_SHAPE = PropTypes.shape({ to: PropTypes.any }); +//Размещение области страниц по вертикали +const P8P_TABLE_PAGINATOR_ALIGN = { + LEFT: "left", + RIGHT: "right", + CENTER: "center" +}; + +//Размещение области страниц по горизонтали +const P8P_TABLE_PAGINATOR_POSITION = { + TOP: "top", + BOTTOM: "bottom", + BOTH: "both" +}; + //Высота кнопки догрузки данных const P8P_TABLE_MORE_HEIGHT = "49px"; @@ -136,6 +151,16 @@ const STYLES = { FILTER_CHIP: { alignItems: "center" }, + PAGINATION: (pagesAlign, position) => ({ + display: "flex", + justifyContent: + pagesAlign === P8P_TABLE_PAGINATOR_ALIGN.LEFT + ? "flex-start" + : pagesAlign === P8P_TABLE_PAGINATOR_ALIGN.CENTER + ? "space-around" + : "flex-end", + ...(position === P8P_TABLE_PAGINATOR_POSITION.TOP ? { paddingBottom: "10px" } : { paddingTop: "10px" }) + }), MORE_BUTTON_CONTAINER: { with: "100%", textAlign: "center", @@ -472,6 +497,10 @@ const P8PTable = ({ orders, filters, size, + pageNumber = 1, + pagesCount = 0, + pagesAlign = P8P_TABLE_PAGINATOR_ALIGN.RIGHT, + pagesPosition = P8P_TABLE_PAGINATOR_POSITION.BOTTOM, fixedHeader = false, fixedColumns = 0, morePages = false, @@ -497,6 +526,7 @@ const P8PTable = ({ onOrderChanged, onFilterChanged, onPagesCountChanged, + onPageChanged, objectsCopier, containerComponent, containerComponentProps @@ -634,6 +664,9 @@ const P8PTable = ({ else setExpanded(pv => ({ ...pv, [rowIndex]: true })); }; + //Отработка изменения страницы + const handlePageChange = (e, page) => onPageChanged && onPageChanged({ page }); + //При перезагрузке данных useEffect(() => { if (reloading) setExpanded({}); @@ -678,6 +711,31 @@ const P8PTable = ({ )); }; + //Генерация области страниц + const renderPagination = position => { + //Признак отображения в конкретной области + const isVisible = [ + position === P8P_TABLE_PAGINATOR_POSITION.TOP ? P8P_TABLE_PAGINATOR_POSITION.TOP : P8P_TABLE_PAGINATOR_POSITION.BOTTOM, + P8P_TABLE_PAGINATOR_POSITION.BOTH + ].includes(pagesPosition); + + //Генерация содержимого + return ( + <> + {pagesCount && pagesCount > 0 && isVisible ? ( + + ) : null} + + ); + }; + //Генерация содержимого return (
@@ -710,6 +768,7 @@ const P8PTable = ({ valueFormatter={valueFormatter} /> ) : null} + {renderPagination(P8P_TABLE_PAGINATOR_POSITION.TOP)} @@ -863,7 +922,8 @@ const P8PTable = ({
- {morePages ? ( + {renderPagination(P8P_TABLE_PAGINATOR_POSITION.BOTTOM)} + {morePages && (!pagesCount || pagesCount <= 0) ? ( )} diff --git a/db/PKG_P8PANELS_SAMPLES.pck b/db/PKG_P8PANELS_SAMPLES.pck index 7c29a0e..5cf3447 100644 --- a/db/PKG_P8PANELS_SAMPLES.pck +++ b/db/PKG_P8PANELS_SAMPLES.pck @@ -231,6 +231,8 @@ create or replace package body PKG_P8PANELS_SAMPLES as SMF_ID => null, SOKOGU => null, NJURPERS_SUBDIV => 0, + SSFR_ORG => null, + STAX_ORG => null, NRN => NRN); end AGNLIST_INSERT; @@ -270,6 +272,75 @@ create or replace package body PKG_P8PANELS_SAMPLES as SAGNINFO PKG_STD.TSTRING; -- Буфер для "Сведений" SAGNNAME PKG_STD.TSTRING; -- Буфер для "Наименования" NAGNTYPE PKG_STD.TREF; -- Буфер для "Типа" + NPAGES_COUNT PKG_STD.TREF; -- Количество отображаемых страниц + + /* Считывание количество страниц таблицы данных */ + function PAGES_COUNT_GET + ( + NCOMPANY in number, -- Организация сеанса + RDG in PKG_P8PANELS_VISUAL.TDG, -- Описание таблицы + RFILTERS in PKG_P8PANELS_VISUAL.TDG_FILTERS, -- Фильтры + NPAGE_SIZE in number -- Количество записей на странице (0 - все) + ) return number -- Количество страниц данных + is + NIDENT PKG_STD.TREF := GEN_IDENT(); -- Идентификатор отбора + CSQL clob; -- Буфер для запроса + ICURSOR integer; -- Курсор для исполнения запроса + NRESULT PKG_STD.TLNUMBER; -- Количество страниц данных + begin + /* Обходим данные */ + begin + /* Добавляем подсказку совместимости */ + CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL); + /* Формируем запрос */ + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select count(AG.RN) NCOUNT'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from AGNLIST AG'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where exists (select ' || PKG_SQL_BUILD.SET_HINT(SHINT => 'INDEX(UP I_USERPRIV_CATALOG_ROLEID)') || ' null'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from USERPRIV UP'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where UP."CATALOG" = AG.CRN'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and UP.ROLEID in (select ' || PKG_SQL_BUILD.SET_HINT(SHINT => 'INDEX(UR I_USERROLES_AUTHID_FK)') || ' UR.ROLEID'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from USERROLES UR where UR.AUTHID = UTILIZER())'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' union all'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' select ' || PKG_SQL_BUILD.SET_HINT(SHINT => 'INDEX(UP I_USERPRIV_CATALOG_AUTHID)') || ' null'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from USERPRIV UP where UP."CATALOG" = AG.CRN and UP.AUTHID = UTILIZER())'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and AG.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT)'); + /* Учтём фильтры */ + PKG_P8PANELS_VISUAL.TDG_FILTERS_SET_QUERY(NIDENT => NIDENT, + NCOMPANY => NCOMPANY, + SUNIT => 'AGNLIST', + SPROCEDURE => 'P_AGNLIST_BASE_COND', + RDATA_GRID => RDG, + RFILTERS => RFILTERS); + /* Разбираем его */ + ICURSOR := PKG_SQL_DML.OPEN_CURSOR(SWHAT => 'SELECT'); + PKG_SQL_DML.PARSE(ICURSOR => ICURSOR, SQUERY => CSQL); + /* Делаем подстановку параметров */ + PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NIDENT', NVALUE => NIDENT); + /* Описываем структуру записи курсора */ + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1); + /* Выполняем */ + if (PKG_SQL_DML.EXECUTE_AND_FETCH(ICURSOR => ICURSOR, BEXACT => false) = 1) then + /* Считываем количество записей */ + PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 1, NVALUE => NRESULT); + /* Если данных не найдено */ + if (NRESULT = 0) then + /* Оставляем одну страницу */ + NRESULT := 1; + else + /* Определяем количество страниц */ + NRESULT := CEIL(NRESULT / NPAGE_SIZE); + end if; + end if; + /* Освобождаем курсор */ + PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); + exception + when others then + PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); + raise; + end; + /* Возвращаем результат */ + return NRESULT; + end PAGES_COUNT_GET; begin /* Читаем фильтры */ RF := PKG_P8PANELS_VISUAL.TDG_FILTERS_FROM_XML(CFILTERS => CFILTERS); @@ -281,7 +352,11 @@ create or replace package body PKG_P8PANELS_SAMPLES as NROW_FROM => NROW_FROM, NROW_TO => NROW_TO); /* Инициализируем таблицу данных */ - RDG := PKG_P8PANELS_VISUAL.TDG_MAKE(BFIXED_HEADER => true, NFIXED_COLUMNS => 2); + RDG := PKG_P8PANELS_VISUAL.TDG_MAKE(BFIXED_HEADER => true, + NFIXED_COLUMNS => 2, + NPAGES_COUNT => 10, + SPAGES_POSITION => PKG_P8PANELS_VISUAL.STABLE_PAGES_POSITION_BOTTOM, + SPAGES_ALIGN => PKG_P8PANELS_VISUAL.STABLE_PAGES_ALIGN_RIGHT); /* Описываем колонки таблицы данных */ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SAGNABBR', @@ -440,6 +515,13 @@ create or replace package body PKG_P8PANELS_SAMPLES as PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); raise; end; + /* Определяем количество отображаемых страниц */ + NPAGES_COUNT := PAGES_COUNT_GET(NCOMPANY => NCOMPANY, RDG => RDG, RFILTERS => RF, NPAGE_SIZE => NPAGE_SIZE); + /* Если количество страниц определено */ + if (NPAGES_COUNT is not null) then + /* Устанавливаем количество отображаемых страниц */ + PKG_P8PANELS_VISUAL.TDG_PAGES_COUNT_SET(RDATA_GRID => RDG, NPAGES_COUNT => NPAGES_COUNT); + end if; /* Сериализуем описание */ COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); end DATA_GRID; diff --git a/db/PKG_P8PANELS_VISUAL.pck b/db/PKG_P8PANELS_VISUAL.pck index 3b660e4..2a37b8a 100644 --- a/db/PKG_P8PANELS_VISUAL.pck +++ b/db/PKG_P8PANELS_VISUAL.pck @@ -9,6 +9,16 @@ create or replace package PKG_P8PANELS_VISUAL as SORDER_DIRECTION_ASC constant PKG_STD.TSTRING := 'ASC'; -- По возрастанию SORDER_DIRECTION_DESC constant PKG_STD.TSTRING := 'DESC'; -- По убыванию + /* Константы - таблица - расположение области страниц по горизонтали */ + STABLE_PAGES_ALIGN_LEFT constant PKG_STD.TSTRING := 'left'; -- Слева + STABLE_PAGES_ALIGN_RIGHT constant PKG_STD.TSTRING := 'right'; -- Справа + STABLE_PAGES_ALIGN_CENTER constant PKG_STD.TSTRING := 'center'; -- По середине + + /* Константы - таблица - расположение области страниц по вертикали */ + STABLE_PAGES_POSITION_TOP constant PKG_STD.TSTRING := 'top'; -- Наверху + STABLE_PAGES_POSITION_BOTTOM constant PKG_STD.TSTRING := 'bottom'; -- Внизу + STABLE_PAGES_POSITION_BOTH constant PKG_STD.TSTRING := 'both'; -- Наверху и внизу + /* Константы - диаграмма Ганта - масштаб */ NGANTT_ZOOM_QUARTER_DAY constant PKG_STD.TNUMBER := 0; -- Четверть дня NGANTT_ZOOM_HALF_DAY constant PKG_STD.TNUMBER := 1; -- Пол дня @@ -122,6 +132,10 @@ create or replace package PKG_P8PANELS_VISUAL as ( BFIXED_HEADER boolean, -- Зафиксировать заголовок NFIXED_COLUMNS PKG_STD.TNUMBER, -- Количество фиксированных колонок + NPAGES_COUNT PKG_STD.TNUMBER, -- Количество страниц + SPAGES_ALIGN PKG_STD.TSTRING, -- Область блока страниц по вертикали (см. константы STABLE_PAGES_ALIGN_*) + SPAGES_POSITION PKG_STD.TSTRING, -- Область блока страниц по горизонтали (см. константы STABLE_PAGES_POSITION_*) + BMORE_PAGES boolean, -- Отображение кнопки догрузки данных (true - отображать, false - не отображать) RCOL_DEFS TDG_COL_DEFS, -- Описание колонок RGROUPS TDG_GROUPS, -- Описание групп RROWS TDG_ROWS -- Данные строк @@ -440,9 +454,20 @@ create or replace package PKG_P8PANELS_VISUAL as function TDG_MAKE ( BFIXED_HEADER in boolean := false, -- Зафиксировать заголовок - NFIXED_COLUMNS in number := 0 -- Количество фиксированных колонок + NFIXED_COLUMNS in number := 0, -- Количество фиксированных колонок + NPAGES_COUNT in number := 0, -- Количество страниц + SPAGES_ALIGN in varchar2 := null, -- Область блока страниц по вертикали (см. константы STABLE_PAGES_ALIGN_*) + SPAGES_POSITION in varchar2 := null, -- Область блока страниц по горизонтали (см. константы STABLE_PAGES_POSITION_*) + BMORE_PAGES in boolean := true -- Отображение кнопки догрузки данных (true - отображать, false - не отображать) ) return TDG; -- Результат работы + /* Установка количества страниц таблицы данных */ + procedure TDG_PAGES_COUNT_SET + ( + RDATA_GRID in out nocopy TDG, -- Описание таблицы данных + NPAGES_COUNT in number -- Количество страниц + ); + /* Поиск описания колонки в таблице данных по наименованию */ function TDG_FIND_COL_DEF ( @@ -839,6 +864,10 @@ create or replace package body PKG_P8PANELS_VISUAL as SRESP_ATTR_EXPANDED constant PKG_STD.TSTRING := 'expanded'; -- Атрибут для флага сокрытия/отображения SRESP_ATTR_FIXED_HEADER constant PKG_STD.TSTRING := 'fixedHeader'; -- Атрибут для флага фиксации заголовка SRESP_ATTR_FIXED_COLUMNS constant PKG_STD.TSTRING := 'fixedColumns'; -- Атрибут для количества фиксированных колонок + SRESP_ATTR_PAGES_COUNT constant PKG_STD.TSTRING := 'pagesCount'; -- Атрибут для количества страниц + SRESP_ATTR_PAGES_ALIGN constant PKG_STD.TSTRING := 'pagesAlign'; -- Атрибут для области блока страниц по вертикали + SRESP_ATTR_PAGES_POSITION constant PKG_STD.TSTRING := 'pagesPosition'; -- Атрибут для области блока страниц по горизонтали + SRESP_ATTR_MORE_PAGES constant PKG_STD.TSTRING := 'morePages'; -- Атрибут для области блока страниц по горизонтали SRESP_ATTR_WIDTH constant PKG_STD.TSTRING := 'width'; -- Атрибут для ширины SRESP_ATTR_HEIGHT constant PKG_STD.TSTRING := 'height'; -- Атрибут для высоты SRESP_ATTR_COLUMNS constant PKG_STD.TSTRING := 'columns'; -- Атрибут для колонок @@ -1420,7 +1449,11 @@ create or replace package body PKG_P8PANELS_VISUAL as function TDG_MAKE ( BFIXED_HEADER in boolean := false, -- Зафиксировать заголовок - NFIXED_COLUMNS in number := 0 -- Количество фиксированных колонок + NFIXED_COLUMNS in number := 0, -- Количество фиксированных колонок + NPAGES_COUNT in number := 0, -- Количество страниц + SPAGES_ALIGN in varchar2 := null, -- Область блока страниц по вертикали (см. константы STABLE_PAGES_ALIGN_*) + SPAGES_POSITION in varchar2 := null, -- Область блока страниц по горизонтали (см. константы STABLE_PAGES_POSITION_*) + BMORE_PAGES in boolean := true -- Отображение кнопки догрузки данных (true - отображать, false - не отображать) ) return TDG -- Результат работы is RRES TDG; -- Буфер для результата @@ -1428,13 +1461,43 @@ create or replace package body PKG_P8PANELS_VISUAL as /* Формируем объект */ RRES.BFIXED_HEADER := COALESCE(BFIXED_HEADER, false); RRES.NFIXED_COLUMNS := COALESCE(NFIXED_COLUMNS, 0); - RRES.RCOL_DEFS := TDG_COL_DEFS(); - RRES.RGROUPS := TDG_GROUPS(); - RRES.RROWS := TDG_ROWS(); + RRES.NPAGES_COUNT := COALESCE(NPAGES_COUNT, 0); + /* Если указано количество страниц */ + if (RRES.NPAGES_COUNT > 0) then + /* При отображении страниц не отображаем кнопку догрузки данных */ + RRES.BMORE_PAGES := false; + /* Предопределяем отображение области страниц параметрами по умолчанию */ + RRES.SPAGES_ALIGN := COALESCE(SPAGES_ALIGN, STABLE_PAGES_ALIGN_RIGHT); + RRES.SPAGES_POSITION := COALESCE(SPAGES_POSITION, STABLE_PAGES_POSITION_BOTTOM); + else + RRES.BMORE_PAGES := COALESCE(BMORE_PAGES, true); + RRES.SPAGES_ALIGN := SPAGES_ALIGN; + RRES.SPAGES_POSITION := SPAGES_POSITION; + end if; + RRES.RCOL_DEFS := TDG_COL_DEFS(); + RRES.RGROUPS := TDG_GROUPS(); + RRES.RROWS := TDG_ROWS(); /* Возвращаем результат */ return RRES; end TDG_MAKE; + /* Установка количества страниц таблицы данных */ + procedure TDG_PAGES_COUNT_SET + ( + RDATA_GRID in out nocopy TDG, -- Описание таблицы данных + NPAGES_COUNT in number -- Количество страниц + ) + is + begin + /* Обновляем значение количества страниц */ + RDATA_GRID.NPAGES_COUNT := COALESCE(NPAGES_COUNT, 0); + /* Если количество страниц меньше или равно нулю */ + if (RDATA_GRID.NPAGES_COUNT <= 0) then + /* Обновляем доступность загрузку по кнопке */ + RDATA_GRID.BMORE_PAGES := true; + end if; + end TDG_PAGES_COUNT_SET; + /* Поиск описания колонки в таблице данных по наименованию */ function TDG_FIND_COL_DEF ( @@ -1536,6 +1599,10 @@ create or replace package body PKG_P8PANELS_VISUAL as /* Cтатические атрибуты заголовка */ PKG_XFAST.ATTR(SNAME => SRESP_ATTR_FIXED_HEADER, BVALUE => RDATA_GRID.BFIXED_HEADER); PKG_XFAST.ATTR(SNAME => SRESP_ATTR_FIXED_COLUMNS, NVALUE => RDATA_GRID.NFIXED_COLUMNS); + PKG_XFAST.ATTR(SNAME => SRESP_ATTR_PAGES_COUNT, NVALUE => RDATA_GRID.NPAGES_COUNT); + PKG_XFAST.ATTR(SNAME => SRESP_ATTR_PAGES_ALIGN, SVALUE => RDATA_GRID.SPAGES_ALIGN); + PKG_XFAST.ATTR(SNAME => SRESP_ATTR_PAGES_POSITION, SVALUE => RDATA_GRID.SPAGES_POSITION); + PKG_XFAST.ATTR(SNAME => SRESP_ATTR_MORE_PAGES, BVALUE => RDATA_GRID.BMORE_PAGES); end TDG_DEF_TO_XML; /* Сериализация таблицы данных */