From 8579bef3fd4b8d89a5814457bdd5fb43c0001edc Mon Sep 17 00:00:00 2001 From: Mark Kats Date: Tue, 25 Aug 2026 09:58:35 +0300 Subject: [PATCH] fix(widgets): finalize MCP widget UI contracts --- .../skills/shd-active-projects/SKILL.md | 12 ++- .../references/project-widget.md | 5 +- .../widgets/_shared/write-actions.css | 16 ++-- .../widgets/acl-matrix/v1/SHA256SUMS | 2 +- .../widgets/acl-matrix/v1/index.html | 46 +++++---- .../widgets/acl-matrix/v1/manifest.json | 6 +- .../widgets/active-projects/v1/SHA256SUMS | 2 +- .../widgets/active-projects/v1/index.html | 55 +++++++---- .../widgets/active-projects/v1/manifest.json | 6 +- .../widgets/activity/v1/SHA256SUMS | 2 +- .../widgets/activity/v1/index.html | 31 +++--- .../widgets/activity/v1/manifest.json | 6 +- .../widgets/agents-health/v1/SHA256SUMS | 2 +- .../widgets/agents-health/v1/index.html | 46 +++++---- .../widgets/agents-health/v1/manifest.json | 6 +- .../widgets/agents/v1/SHA256SUMS | 2 +- .../widgets/agents/v1/index.html | 31 +++--- .../widgets/agents/v1/manifest.json | 6 +- .../widgets/crm-funnel/v1/SHA256SUMS | 2 +- .../widgets/crm-funnel/v1/index.html | 46 +++++---- .../widgets/crm-funnel/v1/manifest.json | 6 +- .../shd-mcp-plugin/widgets/crm/v1/SHA256SUMS | 2 +- .../shd-mcp-plugin/widgets/crm/v1/index.html | 96 +++++++++++-------- .../widgets/crm/v1/manifest.json | 6 +- .../widgets/discussions/v1/SHA256SUMS | 2 +- .../widgets/discussions/v1/index.html | 31 +++--- .../widgets/discussions/v1/manifest.json | 6 +- .../documents-completeness/v1/SHA256SUMS | 2 +- .../documents-completeness/v1/index.html | 46 +++++---- .../documents-completeness/v1/manifest.json | 6 +- .../widgets/documents/v1/SHA256SUMS | 2 +- .../widgets/documents/v1/index.html | 96 +++++++++++-------- .../widgets/documents/v1/manifest.json | 6 +- .../widgets/files/v1/SHA256SUMS | 2 +- .../widgets/files/v1/index.html | 31 +++--- .../widgets/files/v1/manifest.json | 6 +- .../widgets/finance-dashboard/v1/SHA256SUMS | 2 +- .../widgets/finance-dashboard/v1/index.html | 46 +++++---- .../finance-dashboard/v1/manifest.json | 6 +- .../widgets/finance/v1/SHA256SUMS | 2 +- .../widgets/finance/v1/index.html | 96 +++++++++++-------- .../widgets/finance/v1/manifest.json | 6 +- .../widgets/gitea-board/v1/SHA256SUMS | 2 +- .../widgets/gitea-board/v1/index.html | 46 +++++---- .../widgets/gitea-board/v1/manifest.json | 6 +- .../widgets/gitea/v1/SHA256SUMS | 2 +- .../widgets/gitea/v1/index.html | 31 +++--- .../widgets/gitea/v1/manifest.json | 6 +- .../widgets/inventory-warnings/v1/SHA256SUMS | 2 +- .../widgets/inventory-warnings/v1/index.html | 46 +++++---- .../inventory-warnings/v1/manifest.json | 6 +- .../widgets/inventory/v1/SHA256SUMS | 2 +- .../widgets/inventory/v1/index.html | 31 +++--- .../widgets/inventory/v1/manifest.json | 6 +- .../widgets/notes-tree/v1/SHA256SUMS | 2 +- .../widgets/notes-tree/v1/index.html | 46 +++++---- .../widgets/notes-tree/v1/manifest.json | 6 +- .../widgets/notes/v1/SHA256SUMS | 2 +- .../widgets/notes/v1/index.html | 31 +++--- .../widgets/notes/v1/manifest.json | 6 +- .../widgets/notifications/v1/SHA256SUMS | 2 +- .../widgets/notifications/v1/index.html | 31 +++--- .../widgets/notifications/v1/manifest.json | 6 +- .../widgets/organizations/v1/SHA256SUMS | 2 +- .../widgets/organizations/v1/index.html | 31 +++--- .../widgets/organizations/v1/manifest.json | 6 +- .../widgets/project-db-preview/v1/SHA256SUMS | 2 +- .../widgets/project-db-preview/v1/index.html | 50 +++++----- .../project-db-preview/v1/manifest.json | 6 +- .../widgets/project-db/v1/SHA256SUMS | 2 +- .../widgets/project-db/v1/index.html | 35 +++---- .../widgets/project-db/v1/manifest.json | 6 +- .../widgets/project-overview/v1/SHA256SUMS | 2 +- .../widgets/project-overview/v1/index.html | 31 +++--- .../widgets/project-overview/v1/manifest.json | 6 +- .../widgets/project-timeline/v1/SHA256SUMS | 2 +- .../widgets/project-timeline/v1/index.html | 46 +++++---- .../widgets/project-timeline/v1/manifest.json | 6 +- .../widgets/proposal-approvals/v1/SHA256SUMS | 2 +- .../widgets/proposal-approvals/v1/index.html | 46 +++++---- .../proposal-approvals/v1/manifest.json | 6 +- .../widgets/proposals/v1/SHA256SUMS | 2 +- .../widgets/proposals/v1/index.html | 31 +++--- .../widgets/proposals/v1/manifest.json | 6 +- .../widgets/schedule-calendar/v1/SHA256SUMS | 2 +- .../widgets/schedule-calendar/v1/index.html | 46 +++++---- .../schedule-calendar/v1/manifest.json | 6 +- .../widgets/scheduling/v1/SHA256SUMS | 2 +- .../widgets/scheduling/v1/index.html | 31 +++--- .../widgets/scheduling/v1/manifest.json | 6 +- .../widgets/schemes-progress/v1/SHA256SUMS | 2 +- .../widgets/schemes-progress/v1/index.html | 46 +++++---- .../widgets/schemes-progress/v1/manifest.json | 6 +- .../widgets/schemes/v1/SHA256SUMS | 2 +- .../widgets/schemes/v1/index.html | 31 +++--- .../widgets/schemes/v1/manifest.json | 6 +- .../widgets/status-page/v1/SHA256SUMS | 2 +- .../widgets/status-page/v1/index.html | 31 +++--- .../widgets/status-page/v1/manifest.json | 6 +- .../widgets/task-kanban/v1/SHA256SUMS | 2 +- .../widgets/task-kanban/v1/index.html | 46 +++++---- .../widgets/task-kanban/v1/manifest.json | 6 +- .../widgets/tasks/v1/SHA256SUMS | 2 +- .../widgets/tasks/v1/index.html | 96 +++++++++++-------- .../widgets/tasks/v1/manifest.json | 6 +- .../widgets/team-workload/v1/SHA256SUMS | 2 +- .../widgets/team-workload/v1/index.html | 46 +++++---- .../widgets/team-workload/v1/manifest.json | 6 +- .../widgets/terms/v1/SHA256SUMS | 2 +- .../widgets/terms/v1/index.html | 31 +++--- .../widgets/terms/v1/manifest.json | 6 +- 111 files changed, 1074 insertions(+), 880 deletions(-) diff --git a/plugins/shd-mcp-plugin/skills/shd-active-projects/SKILL.md b/plugins/shd-mcp-plugin/skills/shd-active-projects/SKILL.md index f0e0ba0..b2eb254 100644 --- a/plugins/shd-mcp-plugin/skills/shd-active-projects/SKILL.md +++ b/plugins/shd-mcp-plugin/skills/shd-active-projects/SKILL.md @@ -14,14 +14,16 @@ description: Use when the user asks for all active SHD projects, project deadlin `shd_get_project` once per row just to repeat list data. 4. Sort projects with a non-null `deadline` in ascending order. Put projects without a deadline after dated projects; do not invent a date. -5. Return the compact table: +5. If the user is in a UI-capable MCP host, call `shd_render_projects_widget` + after the data call, passing the returned `data` array as `projects` and the + returned `meta` object as `meta`. When rendering succeeds, keep the project + rows inside the widget and give only a short confirmation in the final + response; do not repeat the rows as prose or a Markdown table. +6. If the UI host is unavailable or the render tool returns an error, return + the compact fallback table: `Проект | Дата завершения | Статус` -6. If the user is in a UI-capable MCP host, call `shd_render_projects_widget` - after the data call, passing the returned `data` array as `projects` and the - returned `meta` object as `meta`. The widget is optional; the plain table - remains the fallback for hosts without MCP Apps UI. 7. Preserve the server's project name/code and status. If a deadline is a datetime, format it with its returned timezone when available; otherwise keep the value unmodified and state that timezone data was unavailable. diff --git a/plugins/shd-mcp-plugin/skills/shd-active-projects/references/project-widget.md b/plugins/shd-mcp-plugin/skills/shd-active-projects/references/project-widget.md index 3d79bf2..95e6468 100644 --- a/plugins/shd-mcp-plugin/skills/shd-active-projects/references/project-widget.md +++ b/plugins/shd-mcp-plugin/skills/shd-active-projects/references/project-widget.md @@ -2,4 +2,7 @@ Call the data tool first. Pass only the returned project array and metadata to the render tool. The widget is a presentation layer: it must not invent dates, -statuses or project rows and must keep the plain structured table as fallback. +statuses or project rows. When the render succeeds, keep the rows in the +widget and do not repeat them in the assistant response. Keep the plain +structured table only as the fallback for hosts without MCP Apps UI or when +the render tool fails. diff --git a/plugins/shd-mcp-plugin/widgets/_shared/write-actions.css b/plugins/shd-mcp-plugin/widgets/_shared/write-actions.css index d39a3d2..bb0621c 100644 --- a/plugins/shd-mcp-plugin/widgets/_shared/write-actions.css +++ b/plugins/shd-mcp-plugin/widgets/_shared/write-actions.css @@ -1,20 +1,20 @@ -.shd-widget-actions{margin-top:14px;padding:14px;border:1px solid var(--border,rgba(31,41,55,.16));border-radius:11px;background:var(--surface,#e8edf2);color:var(--text,#1d1f25)} +.shd-widget-actions{margin-top:14px;padding:14px;border:1px solid var(--border,var(--line,rgba(31,41,55,.16)));border-radius:11px;background:var(--surface,var(--panel,#e8edf2));color:var(--text,var(--ink,#1d1f25))} .shd-widget-actions[hidden]{display:none} .shd-widget-actions-header{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px} .shd-widget-actions-selection{overflow:hidden;color:var(--muted,#616670);font-size:12px;text-overflow:ellipsis;white-space:nowrap} -.shd-widget-actions-select,.shd-widget-actions-input{width:100%;border:1px solid var(--border,rgba(31,41,55,.16));border-radius:8px;padding:8px 10px;background:var(--bg,#f8fafc);color:var(--text,#1d1f25)} -.shd-widget-actions-select:focus,.shd-widget-actions-input:focus{border-color:var(--accent,#535963);outline:0;box-shadow:0 0 0 3px var(--accent-soft,rgba(75,85,99,.12))} +.shd-widget-actions-select,.shd-widget-actions-input{width:100%;border:1px solid var(--border,var(--line,rgba(31,41,55,.16)));border-radius:8px;padding:8px 10px;background:var(--bg,#f8fafc);color:var(--text,var(--ink,#1d1f25))} +.shd-widget-actions-select:focus,.shd-widget-actions-input:focus{border-color:var(--accent,#535963);outline:0;box-shadow:0 0 0 3px var(--accent-soft,var(--soft,rgba(75,85,99,.12)))} .shd-widget-actions-form{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin-top:10px} .shd-widget-actions-field{display:grid;gap:4px;color:var(--muted,#616670);font-size:11px} .shd-widget-actions-field:has(textarea){grid-column:span 2} .shd-widget-actions-field input[type=checkbox]{width:18px;height:18px;accent-color:var(--accent,#535963)} -.shd-widget-actions-confirm{display:flex;grid-column:1/-1;align-items:center;gap:7px;color:var(--text,#1d1f25);font-size:12px} +.shd-widget-actions-confirm{display:flex;grid-column:1/-1;align-items:center;gap:7px;color:var(--text,var(--ink,#1d1f25));font-size:12px} .shd-widget-actions-warning,.shd-widget-actions-hint{grid-column:1/-1;color:var(--muted,#616670);font-size:12px} -.shd-widget-actions-danger{color:var(--danger,#b42318)} +.shd-widget-actions-danger{color:var(--danger,var(--bad,#b42318))} .shd-widget-actions-status{min-height:18px;margin-top:9px;color:var(--muted,#616670);font-size:12px} -.shd-widget-actions-status-error{color:var(--danger,#b42318)} +.shd-widget-actions-status-error{color:var(--danger,var(--bad,#b42318))} .shd-widget-actions-buttons{display:flex;justify-content:flex-end;gap:8px;margin-top:10px} -.shd-widget-actions-buttons button{border:1px solid var(--border,rgba(31,41,55,.16));border-radius:8px;padding:8px 11px;background:var(--bg,#f8fafc);color:var(--text,#1d1f25);cursor:pointer} -.shd-widget-actions-buttons button:hover{background:var(--surface-hover,#e1e8ef)} +.shd-widget-actions-buttons button{border:1px solid var(--border,var(--line,rgba(31,41,55,.16)));border-radius:8px;padding:8px 11px;background:var(--bg,#f8fafc);color:var(--text,var(--ink,#1d1f25));cursor:pointer} +.shd-widget-actions-buttons button:hover{background:var(--surface-hover,var(--hover,#e1e8ef))} .shd-widget-actions-buttons button:disabled{cursor:wait;opacity:.62} @media(max-width:600px){.shd-widget-actions-field:has(textarea){grid-column:auto}.shd-widget-actions-header{display:block}.shd-widget-actions-selection{display:block;margin-top:3px}} diff --git a/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/SHA256SUMS b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/SHA256SUMS index 56c1d65..32dcf24 100644 --- a/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/SHA256SUMS +++ b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/SHA256SUMS @@ -1 +1 @@ -818956bcece3e1a64a8f41f51a8bcc19ebcd0c95d1eb9bfa923166dca9660711 index.html +6cf42e69f895b240c8a4018f74d9da3076dfaf3b6f2be9c1ced2417c89c86b79 index.html diff --git a/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/index.html b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/index.html index 747cec0..da6bf68 100644 --- a/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/index.html +++ b/plugins/shd-mcp-plugin/widgets/acl-matrix/v1/index.html @@ -15,24 +15,24 @@ @media(prefers-color-scheme:dark){:root{--bg:#202020;--surface:#292929;--hover:#303336;--line:#43474c;--ink:#eaecf0;--muted:#96999d;--accent:#c7b07a;--soft:rgba(199,176,122,.18);--bad:#ff9a93;--good:#83c995;--button:#241f14;--shadow:0 10px 26px rgba(0,0,0,.34)}} @@ -49,7 +49,9 @@ (function(){ 'use strict'; var DEFAULT_MODULE='acl-matrix'; - var C={ru:{refresh:'Обновить',search:'Поиск по названию, статусу или ID',loading:'Загрузка…',empty:'Нет данных для отображения.',records:'записей',status:'Статус',date:'Дата',value:'Детали',id:'ID',details:'Детали',close:'Закрыть',load:'Не удалось загрузить данные.',detail:'Не удалось загрузить детали.',context:'Для обновления нужен контекст источника',total:'Всего',amount:'Сумма',planned:'План',capacity:'Ёмкость',utilization:'Загрузка',overload:'Перегрузка',warnings:'Предупреждения',complete:'Готово',pending:'Ожидают',approved:'Согласовано',rejected:'Отклонено',progress:'Прогресс',score:'Оценка',member:'Участник',role:'Роль',permissions:'Разрешения',preview:'Предпросмотр',noWarnings:'Предупреждений нет.',health:'Состояние'},en:{refresh:'Refresh',search:'Search by name, status or ID',loading:'Loading…',empty:'No data to display.',records:'records',status:'Status',date:'Date',value:'Details',id:'ID',details:'Details',close:'Close',load:'Could not load data.',detail:'Could not load details.',context:'A source context is required to refresh.',total:'Total',amount:'Amount',planned:'Planned',capacity:'Capacity',utilization:'Utilization',overload:'Overload',warnings:'Warnings',complete:'Complete',pending:'Pending',approved:'Approved',rejected:'Rejected',progress:'Progress',score:'Score',member:'Member',role:'Role',permissions:'Permissions',preview:'Preview',noWarnings:'No warnings.',health:'Health'}}; + var C={ru:{refresh:'Обновить',search:'Поиск по названию, статусу или ID',loading:'Загрузка…',empty:'Нет данных для отображения.',records:'записей',status:'Статус',date:'Дата',value:'Детали',id:'ID',yes:'Да',no:'Нет',details:'Детали',close:'Закрыть',load:'Не удалось загрузить данные.',detail:'Не удалось загрузить детали.',context:'Для обновления нужен контекст источника',total:'Всего',amount:'Сумма',planned:'План',capacity:'Ёмкость',utilization:'Загрузка',overload:'Перегрузка',warnings:'Предупреждения',complete:'Готово',pending:'Ожидают',approved:'Согласовано',rejected:'Отклонено',progress:'Прогресс',score:'Оценка',member:'Участник',role:'Роль',permissions:'Разрешения',preview:'Предпросмотр',noWarnings:'Предупреждений нет.',health:'Состояние'},en:{refresh:'Refresh',search:'Search by name, status or ID',loading:'Loading…',empty:'No data to display.',records:'records',status:'Status',date:'Date',value:'Details',id:'ID',yes:'Yes',no:'No',details:'Details',close:'Close',load:'Could not load data.',detail:'Could not load details.',context:'A source context is required to refresh.',total:'Total',amount:'Amount',planned:'Planned',capacity:'Capacity',utilization:'Utilization',overload:'Overload',warnings:'Warnings',complete:'Complete',pending:'Pending',approved:'Approved',rejected:'Rejected',progress:'Progress',score:'Score',member:'Member',role:'Role',permissions:'Permissions',preview:'Preview',noWarnings:'No warnings.',health:'Health'}}; + var FIELD_LABELS={ru:{id:'ID',key:'Ключ',project_id:'ID проекта',task_project_id:'ID проекта задачи',linked_project_ids:'Связанные проекты',project_code:'Код проекта',base_reference:'Ссылка на базу',base_public_id:'Публичный ID базы',table_public_id:'Публичный ID таблицы',record_public_id:'Публичный ID записи',title:'Название',name:'Название',description:'Описание',status:'Статус',status_id:'ID статуса',is_done:'Завершено',is_complete:'Завершено',section:'Раздел',sort_order:'Порядок сортировки',created_at:'Создано',updated_at:'Обновлено',due_date:'Срок',deadline:'Дедлайн',starts_at:'Начало',ends_at:'Окончание',url:'Ссылка',diagnostic:'Диагностика',message:'Сообщение',type:'Тип',state:'Состояние',phase:'Этап',health:'Состояние',email:'Электронная почта',username:'Имя пользователя',role:'Роль',permissions:'Разрешения',source:'Источник',module:'Модуль',table:'Таблица',fields:'Поля',value:'Значение',stage:'Стадия',approval_status:'Статус согласования',approval_state:'Состояние согласования',priority:'Приоритет',assignee:'Исполнитель',owner:'Владелец',type:'Тип',category:'Категория',permissions:'Разрешения',permission:'Разрешение',read:'Чтение',write:'Запись',manage:'Управление',admin:'Администратор',view:'Просмотр',create:'Создание',update:'Изменение',delete:'Удаление',error:'Ошибка',warning:'Предупреждение',message:'Сообщение',path:'Путь',link:'Ссылка',amount:'Сумма',total:'Итого',quantity:'Количество',available_quantity:'Доступное количество',stock:'Остаток',planned:'План',planned_hours:'Плановые часы',capacity:'Ёмкость',capacity_hours:'Часы ёмкости',utilization:'Загрузка',utilization_percent:'Загрузка, %',overload:'Перегрузка',overload_hours:'Часы перегрузки',score:'Оценка',progress:'Прогресс',completeness_score:'Оценка полноты',completion_percent:'Полнота, %',availability_percent:'Доступность, %',record_count:'Количество записей',revision:'Ревизия',pages:'Страницы',page_count:'Количество страниц',date:'Дата',is_archived:'В архиве',low_stock:'Мало на складе',critical:'Критический',meta:'Метаданные'},en:{id:'ID',key:'Key',project_id:'Project ID',task_project_id:'Task project ID',linked_project_ids:'Linked projects',project_code:'Project code',base_reference:'Base reference',base_public_id:'Public base ID',table_public_id:'Public table ID',record_public_id:'Public record ID',title:'Title',name:'Name',description:'Description',status:'Status',status_id:'Status ID',is_done:'Completed',is_complete:'Completed',section:'Section',sort_order:'Sort order',created_at:'Created',updated_at:'Updated',due_date:'Due date',deadline:'Deadline',starts_at:'Starts',ends_at:'Ends',url:'URL',diagnostic:'Diagnostics',message:'Message',type:'Type',state:'State',phase:'Phase',health:'Health',email:'Email',username:'Username',role:'Role',permissions:'Permissions',source:'Source',module:'Module',table:'Table',fields:'Fields',value:'Value',stage:'Stage',approval_status:'Approval status',approval_state:'Approval state',priority:'Priority',assignee:'Assignee',owner:'Owner',type:'Type',category:'Category',permissions:'Permissions',permission:'Permission',read:'Read',write:'Write',manage:'Manage',admin:'Admin',view:'View',create:'Create',update:'Update',delete:'Delete',error:'Error',warning:'Warning',message:'Message',path:'Path',link:'Link',amount:'Amount',total:'Total',quantity:'Quantity',available_quantity:'Available quantity',stock:'Stock',planned:'Planned',planned_hours:'Planned hours',capacity:'Capacity',capacity_hours:'Capacity hours',utilization:'Utilization',utilization_percent:'Utilization, %',overload:'Overload',overload_hours:'Overload hours',score:'Score',progress:'Progress',completeness_score:'Completeness score',completion_percent:'Completeness, %',availability_percent:'Availability, %',record_count:'Record count',revision:'Revision',pages:'Pages',page_count:'Page count',date:'Date',is_archived:'Archived',low_stock:'Low stock',critical:'Critical',meta:'Metadata'}}; + var VALUE_LABELS={ru:{Tasks_Status_Todo:'К выполнению',Tasks_Status_Done:'Завершено',Tasks_Status_In_Progress:'В работе',Tasks_Status_Review:'На проверке',Modules_Done:'Завершено',todo:'К выполнению',to_do:'К выполнению','to do':'К выполнению',in_progress:'В работе','in progress':'В работе','in-progress':'В работе',in_progress_status:'В работе',done:'Завершено',completed:'Завершено',complete:'Завершено',closed:'Закрыто',active:'Активно',pending:'Ожидает',review:'На проверке',approved:'Согласовано',rejected:'Отклонено',archived:'В архиве',not_set:'Не задано',overdue:'Просрочено',blocked:'Заблокировано',error:'Ошибка',warning:'Предупреждение',maintenance:'Техническое обслуживание',low_stock:'Мало на складе',critical:'Критический',out_of_stock:'Нет на складе',available:'Доступно',unavailable:'Недоступно',read:'Чтение',write:'Запись',manage:'Управление',admin:'Администратор',view:'Просмотр',create:'Создание',update:'Изменение',delete:'Удаление',execute:'Выполнение'},en:{Tasks_Status_Todo:'To do',Tasks_Status_Done:'Done',Tasks_Status_In_Progress:'In progress',Tasks_Status_Review:'In review',Modules_Done:'Done',todo:'To do',to_do:'To do','to do':'To do',in_progress:'In progress','in progress':'In progress','in-progress':'In progress',in_progress_status:'In progress',done:'Done',completed:'Completed',complete:'Complete',closed:'Closed',active:'Active',pending:'Pending',review:'In review',approved:'Approved',rejected:'Rejected',archived:'Archived',not_set:'Not set',overdue:'Overdue',blocked:'Blocked',error:'Error',warning:'Warning',maintenance:'Maintenance',low_stock:'Low stock',critical:'Critical',out_of_stock:'Out of stock',available:'Available',unavailable:'Unavailable',read:'Read',write:'Write',manage:'Manage',admin:'Admin',view:'View',create:'Create',update:'Update',delete:'Delete',execute:'Execute'}}; var M={ discussions:{ru:['Обсуждения','Темы обсуждений с поиском и просмотром сообщений.','Тема','Обновлено','Сообщение'],en:['Discussions','Discussion topics with search and message details.','Topic','Updated','Message']}, notifications:{ru:['Уведомления','Последние уведомления и события модулей.','Уведомление','Время','Источник'],en:['Notifications','Recent notifications and module events.','Notification','Time','Source']}, @@ -134,6 +136,7 @@ function list(x){var p=payload(x)||{};if(Array.isArray(p.items))return p.items;var ps=Array.isArray(state.config.paths)?state.config.paths:(Array.isArray(state.config.arrayPaths)?state.config.arrayPaths:[]),combined=[];for(var i=0;i