bb-plugin-manifest 0.0.0-stage → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +67 -0
- package/PLUGIN_OVERVIEW.md +28 -0
- package/README.md +111 -2
- package/app.tsx +90 -0
- package/components/ui/button.tsx +59 -0
- package/components/ui/card.tsx +83 -0
- package/components/ui/checkbox.tsx +29 -0
- package/components/ui/coarse-pointer-sizing.ts +66 -0
- package/components/ui/dialog.tsx +419 -0
- package/components/ui/hooks/use-compact-viewport.tsx +37 -0
- package/components/ui/hooks/use-media-query.ts +70 -0
- package/components/ui/hooks/use-pointer-coarse.ts +7 -0
- package/components/ui/icon.tsx +8 -0
- package/components/ui/input.tsx +30 -0
- package/components/ui/motion.ts +4 -0
- package/components/ui/overlay-trigger.ts +84 -0
- package/components/ui/responsive-overlay.tsx +895 -0
- package/dist/app.css +2 -0
- package/dist/app.js +3 -0
- package/dist/app.meta.json +11 -0
- package/dist/package.json +1 -0
- package/dist/server.js +85 -0
- package/dist/server.js.map +6 -0
- package/dist/server.meta.json +11 -0
- package/focus.ts +196 -0
- package/hooks/useBrowserDimmingModal.ts +5 -0
- package/icons/dashboard.svg +1 -0
- package/icons/id-card.svg +1 -0
- package/icons/procurement.svg +1 -0
- package/icons/suppliers.svg +1 -0
- package/lib/mcp-client.ts +156 -0
- package/lib/portal-scope.ts +15 -0
- package/lib/tools.ts +842 -0
- package/lib/utils.ts +17 -0
- package/package.json +95 -4
- package/server.ts +1152 -0
- package/skills/manifest-outreach/SKILL.md +394 -0
- package/ui/CardTab.tsx +629 -0
- package/ui/CompanyPeek.tsx +277 -0
- package/ui/ConnectSection.tsx +85 -0
- package/ui/FilterSelect.tsx +113 -0
- package/ui/OutreachPage.tsx +102 -0
- package/ui/RegistryList.tsx +270 -0
- package/ui/SuppliersList.tsx +167 -0
- package/ui/dashboard/Accessory.tsx +15 -0
- package/ui/dashboard/DashboardPage.tsx +197 -0
- package/ui/dashboard/FilterBar.tsx +153 -0
- package/ui/dashboard/Widgets.tsx +410 -0
- package/ui/dashboard/state.ts +248 -0
- package/ui/directives.tsx +308 -0
- package/ui/hooks.ts +215 -0
- package/ui/labels.ts +199 -0
- package/ui/mail/CompanyMail.tsx +230 -0
- package/ui/mail/LetterView.tsx +134 -0
- package/ui/mail/MailPage.tsx +517 -0
- package/ui/mail/MailingView.tsx +324 -0
- package/ui/mail/TemplateEditor.tsx +393 -0
- package/ui/mail/attachments.tsx +296 -0
- package/ui/mail/common.tsx +291 -0
- package/ui/mail/hubTabs.ts +35 -0
- package/ui/mail/send.tsx +593 -0
- package/ui/manifest/index.tsx +122 -0
- package/ui/manifest/manifest.css +185 -0
- package/ui/map/CoverageMap.tsx +346 -0
- package/ui/map/world.ts +7 -0
- package/ui/procurement/CatalogDetail.tsx +98 -0
- package/ui/procurement/ChoiceTable.tsx +246 -0
- package/ui/procurement/CompanyAssortment.tsx +196 -0
- package/ui/procurement/Countries.tsx +530 -0
- package/ui/procurement/Matching.tsx +429 -0
- package/ui/procurement/NeedSheet.tsx +488 -0
- package/ui/procurement/Review.tsx +346 -0
- package/ui/procurement/file.ts +17 -0
- package/ui/procurement/grid.tsx +111 -0
- package/ui/procurement/nav.ts +17 -0
- package/ui/procurement/paths.ts +27 -0
- package/ui/suppliers.css +34 -0
- package/ui/types.ts +307 -0
- package/ui/workspace/Chips.tsx +214 -0
- package/ui/workspace/InboundView.tsx +119 -0
- package/ui/workspace/ObjectPanel.tsx +304 -0
- package/ui/workspace/compose.tsx +88 -0
- package/ui/workspace/intent.ts +97 -0
- package/ui/workspace/nav.tsx +82 -0
- package/ui/workspace/state.ts +289 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Manifest Plugins for bb — Proprietary License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dmitry Petrakov. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This repository and all files in it (the "Software") are proprietary. The Software is
|
|
6
|
+
not open source. Its source code is published only so that authorized users can
|
|
7
|
+
install it in bb from a public URL.
|
|
8
|
+
|
|
9
|
+
1. Permitted use
|
|
10
|
+
|
|
11
|
+
You may download, install and run the Software only if you are:
|
|
12
|
+
|
|
13
|
+
a) a user authorized by the copyright holder, or
|
|
14
|
+
b) an employee or contractor of an organization that has a valid agreement with
|
|
15
|
+
the copyright holder for the Manifest service,
|
|
16
|
+
|
|
17
|
+
and only to access a Manifest instance provided under such an agreement, for as
|
|
18
|
+
long as the agreement is in force.
|
|
19
|
+
|
|
20
|
+
You may view the source code on GitHub to the extent allowed by the GitHub Terms
|
|
21
|
+
of Service.
|
|
22
|
+
|
|
23
|
+
2. Restrictions
|
|
24
|
+
|
|
25
|
+
Except as expressly permitted above, you may not, without prior written permission
|
|
26
|
+
of the copyright holder:
|
|
27
|
+
|
|
28
|
+
a) copy, modify, adapt, translate or create derivative works of the Software;
|
|
29
|
+
b) distribute, publish, sublicense, sell, rent, lend or otherwise transfer the
|
|
30
|
+
Software or any part of it to any third party;
|
|
31
|
+
c) use the Software, in whole or in part, with any system other than Manifest, or
|
|
32
|
+
to build a competing product or service;
|
|
33
|
+
d) remove or alter this notice or any copyright notice in the Software.
|
|
34
|
+
|
|
35
|
+
3. Ownership
|
|
36
|
+
|
|
37
|
+
The Software is licensed, not sold. The copyright holder retains all rights,
|
|
38
|
+
title and interest in the Software. No rights are granted by implication or
|
|
39
|
+
estoppel beyond those stated in section 1.
|
|
40
|
+
|
|
41
|
+
4. Third-party components
|
|
42
|
+
|
|
43
|
+
Third-party packages used by the Software are licensed under their own terms,
|
|
44
|
+
as stated in their respective packages. This license does not apply to them.
|
|
45
|
+
|
|
46
|
+
5. Termination
|
|
47
|
+
|
|
48
|
+
This license ends automatically when your authorization or your organization's
|
|
49
|
+
agreement ends, or if you breach any of its terms. On termination you must stop
|
|
50
|
+
using the Software and delete all copies in your possession.
|
|
51
|
+
|
|
52
|
+
6. No warranty
|
|
53
|
+
|
|
54
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
55
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
56
|
+
FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT, EXCEPT AS EXPRESSLY AGREED IN A
|
|
57
|
+
SEPARATE WRITTEN AGREEMENT WITH THE COPYRIGHT HOLDER.
|
|
58
|
+
|
|
59
|
+
7. Limitation of liability
|
|
60
|
+
|
|
61
|
+
TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
|
62
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
63
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
64
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
65
|
+
|
|
66
|
+
For licensing questions, contact the copyright holder through
|
|
67
|
+
https://github.com/dpetrakov.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Работайте с реестром потенциальных поставщиков Manifest прямо в BB: список слева,
|
|
2
|
+
карточка организации справа, чат с агентом по карточке в центре, а на отдельной
|
|
3
|
+
странице — дашборд аутрича с темами-чатами.
|
|
4
|
+
|
|
5
|
+
## Что вы получаете
|
|
6
|
+
|
|
7
|
+
- Реестр поставщиков по регионам и странам с приоритетом работы, поиском и фильтрами.
|
|
8
|
+
- Карточку организации: реквизиты, каналы связи, контактные лица, статус, касания,
|
|
9
|
+
следующий шаг, ответственный и комментарии — в пределах ваших прав в Manifest.
|
|
10
|
+
- **Дашборд аутрича**: очередь «Сегодня» (ждут нашего ответа, просрочено, на сегодня,
|
|
11
|
+
готовы и не тронуты), воронка с оттоком по причинам, регионы, матрица застоя,
|
|
12
|
+
качество данных и лента «что изменилось с прошлого визита».
|
|
13
|
+
- **Темы** — несколько чатов с агентом на дашборде, у каждой свой фильтр. Агент
|
|
14
|
+
показывает выборку на дашборде, выводит живые списки организаций и готовит правки
|
|
15
|
+
пачками: применяете и откатываете вы кнопкой.
|
|
16
|
+
- Счётчик «ждут ответа + просрочено» на вкладке «Поставщики» и пункте дашборда.
|
|
17
|
+
|
|
18
|
+
## Как это работает
|
|
19
|
+
|
|
20
|
+
Данные, расчёт метрик и права живут в Manifest. Плагин подключается к нему по адресу,
|
|
21
|
+
email и паролю для плагина; пароль один раз обменивается на токен. Каждое изменение
|
|
22
|
+
агента видно в истории с пометкой «агент BB». Отозвать доступ можно в Manifest.
|
|
23
|
+
|
|
24
|
+
## Для агентов
|
|
25
|
+
|
|
26
|
+
В чате организации и в темах дашборда агенту доступны инструменты `outreach_*`;
|
|
27
|
+
навык `manifest-outreach` описывает их, директивы `::manifest-companies` и
|
|
28
|
+
`::manifest-batch` и правило: массовые правки применяет человек.
|
package/README.md
CHANGED
|
@@ -1,3 +1,112 @@
|
|
|
1
|
-
#
|
|
1
|
+
# manifest — Manifest outreach workspace for bb
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A [bb](https://github.com/get-bb/bb) plugin that connects bb to **Manifest**, a private
|
|
4
|
+
operations service, and gives the team its supplier outreach workspace inside bb. The
|
|
5
|
+
plugin interface and the agent skill are in Russian.
|
|
6
|
+
|
|
7
|
+
- **Left: registry.** The plugin's own sidebar list «Потенциальные поставщики»
|
|
8
|
+
(“Potential suppliers”): search and filters by region, country (with search inside
|
|
9
|
+
the list), priority and status. A button in the sidebar footer, tinted in Manifest's
|
|
10
|
+
soft green, switches the sidebar between the suppliers and the previous list;
|
|
11
|
+
opening «Аутрич» (“Outreach”) switches it on by itself.
|
|
12
|
+
- **Right: card.** The «Карточка» (“Card”) tab: company details, countries, contact
|
|
13
|
+
channels, contact persons, status, priority, comments and change history. Editing
|
|
14
|
+
requires the `outreach.manage` permission in Manifest.
|
|
15
|
+
- **Middle: chat.** A bb thread bound to the company. The agent reads and edits it
|
|
16
|
+
with Manifest tools within the user's permissions; each change is recorded in the
|
|
17
|
+
history as «агент BB» (“bb agent”).
|
|
18
|
+
|
|
19
|
+
- **Dashboard (0.2.0).** The «Дашборд аутрича» page: today queue, funnel, regions,
|
|
20
|
+
stagnation matrix, data quality and recent changes, with several topic chats. The
|
|
21
|
+
topic agent filters the dashboard, shows live company lists and prepares bulk edits
|
|
22
|
+
that a person applies or reverts.
|
|
23
|
+
|
|
24
|
+
Manifest is the MCP server and the only source of data and permissions. The plugin
|
|
25
|
+
keeps just an access token (a secret setting on the bb backend); the password is used
|
|
26
|
+
once to sign in.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
For a release published to npm, install the prebuilt package on the computer
|
|
31
|
+
running your bb server (an enrolled agent machine can be a different computer):
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
bb plugin install npm:bb-plugin-manifest@latest
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This route does not need Git or Xcode Command Line Tools. Until the first npm
|
|
38
|
+
release is published, use the existing Git source (which requires Git):
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
bb plugin install https://github.com/dpetrakov/manifest-bb-plugins --plugin manifest
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then open *Settings → Plugins → Manifest → «Подключение к Manifest»* (“Connection to
|
|
45
|
+
Manifest”) and enter the Manifest URL, your email and your plugin password. The
|
|
46
|
+
password is set in Manifest by an administrator («Пользователи и права» → «Плагин BB»)
|
|
47
|
+
or by yourself (click your name at the bottom of the Manifest menu).
|
|
48
|
+
|
|
49
|
+
## Layout
|
|
50
|
+
|
|
51
|
+
| Path | What it is |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `server.ts` | Backend: settings, sign-in and sign-out, RPC for the panels, agent tools, agent configuration per company thread. |
|
|
54
|
+
| `app.tsx` | UI slots: sidebar list and its footer button, navigation pages, «Карточка» tab, directives, settings section. |
|
|
55
|
+
| `lib/mcp-client.ts` | Minimal MCP client over HTTPS (`tools/call`, Bearer token, actor kind header). |
|
|
56
|
+
| `lib/tools.ts` | Agent tool schemas and the list of tools available to panels. |
|
|
57
|
+
| `ui/` | React components: registry list, filters, card, connection settings; `SuppliersList.tsx` and `suppliers.css` — the sidebar list, its switch and the footer button tone. |
|
|
58
|
+
| `ui/dashboard/` | The outreach dashboard: page, widgets, topic filter, attention counter. |
|
|
59
|
+
| `ui/directives.tsx` | Message directives `::manifest-companies` and `::manifest-batch`. |
|
|
60
|
+
| `skills/manifest-outreach/` | Agent skill: registry rules and tool usage. |
|
|
61
|
+
| `PLUGIN_OVERVIEW.md` | Description shown inside bb (in Russian). |
|
|
62
|
+
| `tests/` | vitest (backend on a fake plugin host, UI with `renderSlot`) and `node:test` (MCP client). |
|
|
63
|
+
|
|
64
|
+
## Development
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
npm ci
|
|
68
|
+
npm run check # tsc --noEmit + vitest + node:test
|
|
69
|
+
bb plugin build . # dist/
|
|
70
|
+
|
|
71
|
+
# Optional: check the contract against a running Manifest
|
|
72
|
+
MANIFEST_URL=https://manifest.example.com MANIFEST_EMAIL=you@example.com MANIFEST_PASSWORD=… \
|
|
73
|
+
node --experimental-strip-types --test tests/mcp-client.test.mjs
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The plugin is developed together with Manifest and published to
|
|
77
|
+
[manifest-bb-plugins](https://github.com/dpetrakov/manifest-bb-plugins) by a release
|
|
78
|
+
script. The Manifest contract is version 1 (`manifest_whoami.contract`); on a mismatch
|
|
79
|
+
the plugin asks to be updated instead of failing.
|
|
80
|
+
|
|
81
|
+
### Publishing a prebuilt npm package
|
|
82
|
+
|
|
83
|
+
Keep the package name `bb-plugin-manifest` so the bb plugin id stays `manifest`.
|
|
84
|
+
The `files` allowlist includes the built bundles, their metadata, the plugin
|
|
85
|
+
sources, icons, skill, and proprietary license. Tests and local settings are
|
|
86
|
+
excluded. `npm pack` runs `prepack` to rebuild bundles for the package version.
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
npm run check
|
|
90
|
+
npm pack --dry-run
|
|
91
|
+
npm pack --pack-destination /absolute/path/to/release
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Inspect the archive before publishing. It must contain `dist/server.js`,
|
|
95
|
+
`dist/server.meta.json`, `dist/app.js`, `dist/app.meta.json`, and `dist/app.css`;
|
|
96
|
+
both metadata files must match the package id and version. Log in with
|
|
97
|
+
`npm login --auth-type=web --registry=https://registry.npmjs.org/`, then publish
|
|
98
|
+
the reviewed archive:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
npm publish /absolute/path/to/release/bb-plugin-manifest-X.Y.Z.tgz --access public --registry=https://registry.npmjs.org/
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Complete any npm authentication prompt yourself. Verify the release with
|
|
105
|
+
`npm view bb-plugin-manifest version dist.integrity`, then test a fresh npm
|
|
106
|
+
install in a separate bb server. Users who installed with `@latest` update with
|
|
107
|
+
`bb plugin update manifest`. An existing Git installation keeps tracking Git;
|
|
108
|
+
do not remove it just to switch sources, because removal deletes its settings.
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
Proprietary, not open source. See [LICENSE](https://github.com/dpetrakov/manifest-bb-plugins/blob/main/LICENSE).
|
package/app.tsx
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// bb-plugin-manifest — frontend (EP-069..EP-071, docs/outreach/bb-plugin.md).
|
|
2
|
+
//
|
|
3
|
+
// Left: «Потенциальные поставщики» — the plugin's own sidebar thread list, switched
|
|
4
|
+
// on by a footer button (and by the «Аутрич» section); the button returns the
|
|
5
|
+
// previous list. No sidebar-tabs host since 0.5.0.
|
|
6
|
+
// W-18 (ADR-049): chats are native BB threads; the object of a thread (organisation,
|
|
7
|
+
// mailing, template, topic, inbound) is a tab of the thread's side panel. Plugin pages
|
|
8
|
+
// are pults: lists, an object on the whole screen, its chats and «Новый чат».
|
|
9
|
+
// «Дашборд аутрича» (W-15): metrics, queue and topic chats; directives render
|
|
10
|
+
// live company lists and batch cards inside the agent's messages.
|
|
11
|
+
import { definePluginApp } from "@get-bb/plugin-sdk/app";
|
|
12
|
+
import { ConnectSection } from "./ui/ConnectSection";
|
|
13
|
+
import { PANEL_ID, PANEL_PATH } from "./ui/hooks";
|
|
14
|
+
import { OutreachPage } from "./ui/OutreachPage";
|
|
15
|
+
import { FOOTER_LABEL, SuppliersList, SuppliersSwitch, requestSuppliersToggle } from "./ui/SuppliersList";
|
|
16
|
+
import "./ui/suppliers.css";
|
|
17
|
+
import "./ui/manifest/manifest.css";
|
|
18
|
+
import { DashboardPage } from "./ui/dashboard/DashboardPage";
|
|
19
|
+
import { AttentionAccessory } from "./ui/dashboard/Accessory";
|
|
20
|
+
import { DASHBOARD_ID, DASHBOARD_PATH } from "./ui/dashboard/state";
|
|
21
|
+
import { BatchDirective, CompaniesDirective } from "./ui/directives";
|
|
22
|
+
import { MailPage } from "./ui/mail/MailPage";
|
|
23
|
+
import { LetterChip, MailingChip } from "./ui/workspace/Chips";
|
|
24
|
+
import { MAIL_ID, MAIL_PATH } from "./ui/mail/common";
|
|
25
|
+
import { NeedsPage } from "./ui/procurement/NeedSheet";
|
|
26
|
+
import { NEEDS_ID, NEEDS_PATH } from "./ui/procurement/paths";
|
|
27
|
+
import { FocusHeader, ObjectPanel } from "./ui/workspace/ObjectPanel";
|
|
28
|
+
import { BESIDE_NEW_PANEL, BESIDE_PANEL, OBJECT_PANEL } from "./ui/workspace/state";
|
|
29
|
+
import { ComposeBanner, NEW_COMPANY_PANEL, NewCompanyPanel } from "./ui/workspace/compose";
|
|
30
|
+
|
|
31
|
+
export default definePluginApp((app) => {
|
|
32
|
+
app.slots.navPanel({
|
|
33
|
+
id: PANEL_ID,
|
|
34
|
+
title: "Аутрич",
|
|
35
|
+
icon: "Globe",
|
|
36
|
+
path: PANEL_PATH,
|
|
37
|
+
component: OutreachPage,
|
|
38
|
+
});
|
|
39
|
+
// W-15: дашборд аутрича с темами-чатами; карточка — по цели вкладки.
|
|
40
|
+
app.slots.navPanel({
|
|
41
|
+
id: DASHBOARD_ID,
|
|
42
|
+
title: "Дашборд аутрича",
|
|
43
|
+
icon: "manifest/dashboard",
|
|
44
|
+
path: DASHBOARD_PATH,
|
|
45
|
+
component: DashboardPage,
|
|
46
|
+
experimental_sidebarAccessory: AttentionAccessory,
|
|
47
|
+
});
|
|
48
|
+
// W-16: почта — шаблоны (с чатом по шаблону), юрлица и отправители, неразобранные входящие.
|
|
49
|
+
app.slots.navPanel({ id: MAIL_ID, title: "Почта аутрича", icon: "Mail", path: MAIL_PATH, component: MailPage });
|
|
50
|
+
// ADR-051 (W-19): what we need — the procurement sheet, as an object beside a chat.
|
|
51
|
+
app.slots.navPanel({ id: NEEDS_ID, title: "Закупочный лист", icon: "manifest/procurement", path: NEEDS_PATH, component: NeedsPage });
|
|
52
|
+
app.slots.messageDirective({ id: "manifest-companies", component: CompaniesDirective });
|
|
53
|
+
app.slots.messageDirective({ id: "manifest-batch", component: BatchDirective });
|
|
54
|
+
// W-17: письмо организации «как уйдёт» — черновик из Manifest, обновляется после правки агента.
|
|
55
|
+
app.slots.messageDirective({ id: "manifest-letter", component: LetterChip });
|
|
56
|
+
// W-17: рассылка — одно письмо, много получателей, письмо каждого «как уйдёт».
|
|
57
|
+
app.slots.messageDirective({ id: "manifest-mailing", component: MailingChip });
|
|
58
|
+
// Список поставщиков в сайдбаре и кнопка-переключатель в подвале (цвет — suppliers.css).
|
|
59
|
+
app.slots.experimental_threadList({
|
|
60
|
+
id: "suppliers",
|
|
61
|
+
title: "Потенциальные поставщики",
|
|
62
|
+
description: "Реестр Manifest вместо списка тредов; кнопка в подвале возвращает прежний список.",
|
|
63
|
+
component: SuppliersList,
|
|
64
|
+
});
|
|
65
|
+
app.slots.experimental_appOverlay({ id: "suppliers-switch", component: SuppliersSwitch });
|
|
66
|
+
app.experimental_sidebarFooter.register({
|
|
67
|
+
kind: "action",
|
|
68
|
+
id: "suppliers",
|
|
69
|
+
label: FOOTER_LABEL,
|
|
70
|
+
icon: "manifest/suppliers",
|
|
71
|
+
onActivate: requestSuppliersToggle,
|
|
72
|
+
});
|
|
73
|
+
// W-18 (ADR-049): объект треда — во вкладке боковой панели родного треда BB; кнопка в
|
|
74
|
+
// шапке треда показывает, что открыто, и сама открывает панель.
|
|
75
|
+
app.slots.threadPanelAction({ id: OBJECT_PANEL, title: "Manifest", icon: "manifest/id-card", layout: "flush", component: ObjectPanel });
|
|
76
|
+
app.slots.experimental_threadHeaderAction({ id: "focus", title: "Объект Manifest", component: FocusHeader });
|
|
77
|
+
// Организация без чата открывается экраном нового треда BB: карточка — в его боковой
|
|
78
|
+
// панели, над полем — баннер; первое сообщение создаёт тред, привязанный к организации.
|
|
79
|
+
app.slots.experimental_newThreadPanelAction({ id: NEW_COMPANY_PANEL, title: "Manifest", icon: "manifest/id-card", layout: "flush", component: NewCompanyPanel });
|
|
80
|
+
// A second object beside the main one (Cmd/Ctrl-click, «Рядом» in the list): its own tab.
|
|
81
|
+
app.slots.threadPanelAction({ id: BESIDE_PANEL, title: "Manifest · рядом", icon: "manifest/id-card", layout: "flush", component: ObjectPanel });
|
|
82
|
+
app.slots.experimental_newThreadPanelAction({ id: BESIDE_NEW_PANEL, title: "Manifest · рядом", icon: "manifest/id-card", layout: "flush", component: NewCompanyPanel });
|
|
83
|
+
app.composer.customize({ id: "company-intent", scopes: ["new-thread"], banners: [{ id: "company", chrome: "bare", component: ComposeBanner }] });
|
|
84
|
+
app.slots.settingsSection({
|
|
85
|
+
id: "connect",
|
|
86
|
+
title: "Подключение к Manifest",
|
|
87
|
+
description: "Вход по email и паролю для плагина; данные и права — в Manifest.",
|
|
88
|
+
component: ConnectSection,
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils";
|
|
6
|
+
import { CONTROL_HOVER_TRANSITION } from "./motion.js";
|
|
7
|
+
|
|
8
|
+
const buttonVariants = cva(
|
|
9
|
+
`inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ${CONTROL_HOVER_TRANSITION} focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_[data-icon-root]]:pointer-events-none [&_[data-icon-root]]:size-4 [&_[data-icon-root]]:shrink-0`,
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
default: "bg-foreground text-background hover:bg-foreground/90",
|
|
14
|
+
destructive:
|
|
15
|
+
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
16
|
+
outline:
|
|
17
|
+
"border border-input bg-transparent hover:bg-state-hover hover:text-foreground",
|
|
18
|
+
secondary:
|
|
19
|
+
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
20
|
+
ghost:
|
|
21
|
+
"hover:bg-state-hover hover:text-foreground aria-pressed:bg-state-active aria-pressed:text-foreground aria-pressed:hover:bg-state-active data-[state=open]:bg-state-active data-[state=open]:text-foreground data-[state=open]:hover:bg-state-active",
|
|
22
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
23
|
+
},
|
|
24
|
+
size: {
|
|
25
|
+
default: "h-9 px-4 py-2",
|
|
26
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
27
|
+
lg: "h-10 rounded-md px-8",
|
|
28
|
+
icon: "h-9 w-9",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
defaultVariants: {
|
|
32
|
+
variant: "default",
|
|
33
|
+
size: "default",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export interface ButtonProps
|
|
39
|
+
extends
|
|
40
|
+
Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "title">,
|
|
41
|
+
VariantProps<typeof buttonVariants> {
|
|
42
|
+
asChild?: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
46
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
47
|
+
const Comp = asChild ? Slot : "button";
|
|
48
|
+
return (
|
|
49
|
+
<Comp
|
|
50
|
+
className={cn(buttonVariants({ variant, size, className }))}
|
|
51
|
+
ref={ref}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
Button.displayName = "Button";
|
|
58
|
+
|
|
59
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
const Card = React.forwardRef<
|
|
6
|
+
HTMLDivElement,
|
|
7
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
8
|
+
>(({ className, ...props }, ref) => (
|
|
9
|
+
<div
|
|
10
|
+
ref={ref}
|
|
11
|
+
className={cn(
|
|
12
|
+
"rounded-lg border border-border bg-card text-card-foreground",
|
|
13
|
+
className,
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
));
|
|
18
|
+
Card.displayName = "Card";
|
|
19
|
+
|
|
20
|
+
const CardHeader = React.forwardRef<
|
|
21
|
+
HTMLDivElement,
|
|
22
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
23
|
+
>(({ className, ...props }, ref) => (
|
|
24
|
+
<div
|
|
25
|
+
ref={ref}
|
|
26
|
+
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
));
|
|
30
|
+
CardHeader.displayName = "CardHeader";
|
|
31
|
+
|
|
32
|
+
const CardTitle = React.forwardRef<
|
|
33
|
+
HTMLDivElement,
|
|
34
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
35
|
+
>(({ className, ...props }, ref) => (
|
|
36
|
+
<div
|
|
37
|
+
ref={ref}
|
|
38
|
+
className={cn("font-semibold leading-none tracking-tight", className)}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
41
|
+
));
|
|
42
|
+
CardTitle.displayName = "CardTitle";
|
|
43
|
+
|
|
44
|
+
const CardDescription = React.forwardRef<
|
|
45
|
+
HTMLDivElement,
|
|
46
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
47
|
+
>(({ className, ...props }, ref) => (
|
|
48
|
+
<div
|
|
49
|
+
ref={ref}
|
|
50
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
));
|
|
54
|
+
CardDescription.displayName = "CardDescription";
|
|
55
|
+
|
|
56
|
+
const CardContent = React.forwardRef<
|
|
57
|
+
HTMLDivElement,
|
|
58
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
59
|
+
>(({ className, ...props }, ref) => (
|
|
60
|
+
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
|
61
|
+
));
|
|
62
|
+
CardContent.displayName = "CardContent";
|
|
63
|
+
|
|
64
|
+
const CardFooter = React.forwardRef<
|
|
65
|
+
HTMLDivElement,
|
|
66
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
67
|
+
>(({ className, ...props }, ref) => (
|
|
68
|
+
<div
|
|
69
|
+
ref={ref}
|
|
70
|
+
className={cn("flex items-center p-6 pt-0", className)}
|
|
71
|
+
{...props}
|
|
72
|
+
/>
|
|
73
|
+
));
|
|
74
|
+
CardFooter.displayName = "CardFooter";
|
|
75
|
+
|
|
76
|
+
export {
|
|
77
|
+
Card,
|
|
78
|
+
CardHeader,
|
|
79
|
+
CardFooter,
|
|
80
|
+
CardTitle,
|
|
81
|
+
CardDescription,
|
|
82
|
+
CardContent,
|
|
83
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../../lib/utils";
|
|
5
|
+
import { CONTROL_HOVER_TRANSITION } from "./motion.js";
|
|
6
|
+
import { Icon } from "../../components/ui/icon.js";
|
|
7
|
+
|
|
8
|
+
const Checkbox = React.forwardRef<
|
|
9
|
+
React.ComponentRef<typeof CheckboxPrimitive.Root>,
|
|
10
|
+
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
|
|
11
|
+
>(({ className, ...props }, ref) => (
|
|
12
|
+
<CheckboxPrimitive.Root
|
|
13
|
+
ref={ref}
|
|
14
|
+
className={cn(
|
|
15
|
+
`peer size-4 shrink-0 rounded-sm border border-input shadow-xs ${CONTROL_HOVER_TRANSITION} focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-foreground data-[state=checked]:bg-foreground data-[state=checked]:text-background`,
|
|
16
|
+
className,
|
|
17
|
+
)}
|
|
18
|
+
{...props}
|
|
19
|
+
>
|
|
20
|
+
<CheckboxPrimitive.Indicator
|
|
21
|
+
className={cn("flex items-center justify-center text-current")}
|
|
22
|
+
>
|
|
23
|
+
<Icon name="Check" className="size-3.5" />
|
|
24
|
+
</CheckboxPrimitive.Indicator>
|
|
25
|
+
</CheckboxPrimitive.Root>
|
|
26
|
+
));
|
|
27
|
+
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
|
28
|
+
|
|
29
|
+
export { Checkbox };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export const COARSE_POINTER_TEXT_BASE_CLASS =
|
|
2
|
+
"text-sm max-md:pointer-coarse:text-base";
|
|
3
|
+
|
|
4
|
+
export const COARSE_POINTER_TEXT_SM_CLASS =
|
|
5
|
+
"text-xs max-md:pointer-coarse:text-sm";
|
|
6
|
+
|
|
7
|
+
export const COARSE_POINTER_ICON_SIZE_CLASS =
|
|
8
|
+
"size-4 max-md:pointer-coarse:size-5";
|
|
9
|
+
|
|
10
|
+
export const COARSE_POINTER_ICON_SIZE_SHRINK_CLASS =
|
|
11
|
+
"size-4 shrink-0 max-md:pointer-coarse:size-5";
|
|
12
|
+
|
|
13
|
+
export const COARSE_POINTER_COMPACT_ICON_SIZE_CLASS =
|
|
14
|
+
"size-3.5 max-md:pointer-coarse:size-5";
|
|
15
|
+
|
|
16
|
+
export const COARSE_POINTER_COMPACT_ICON_SIZE_SHRINK_CLASS =
|
|
17
|
+
"size-3.5 shrink-0 max-md:pointer-coarse:size-5";
|
|
18
|
+
|
|
19
|
+
export const COARSE_POINTER_DOT_SIZE_CLASS =
|
|
20
|
+
"size-1.5 max-md:pointer-coarse:size-2";
|
|
21
|
+
|
|
22
|
+
export const COARSE_POINTER_GLYPH_BOX_CLASS =
|
|
23
|
+
"h-4 w-4 max-md:pointer-coarse:h-5 max-md:pointer-coarse:w-5";
|
|
24
|
+
|
|
25
|
+
export const COARSE_POINTER_CHECK_SLOT_CLASS =
|
|
26
|
+
"h-3.5 w-3.5 max-md:pointer-coarse:h-5 max-md:pointer-coarse:w-5";
|
|
27
|
+
|
|
28
|
+
const HEADER_ICON_BUTTON_BOX_CLASS =
|
|
29
|
+
"h-[28px] w-[28px] rounded-md p-0 max-md:pointer-coarse:h-[36px] max-md:pointer-coarse:w-[36px]";
|
|
30
|
+
|
|
31
|
+
export const COARSE_POINTER_HEADER_ICON_BUTTON_CLASS = `${HEADER_ICON_BUTTON_BOX_CLASS} [&_[data-icon-root]]:size-[16px] max-md:pointer-coarse:[&_[data-icon-root]]:size-[20px]`;
|
|
32
|
+
|
|
33
|
+
export const COARSE_POINTER_HEADER_REDUCED_GLYPH_ICON_BUTTON_CLASS = `${HEADER_ICON_BUTTON_BOX_CLASS} [&_[data-icon-root]]:size-[13px] max-md:pointer-coarse:[&_[data-icon-root]]:size-[16px]`;
|
|
34
|
+
|
|
35
|
+
export const COARSE_POINTER_COMPACT_ICON_BUTTON_CLASS =
|
|
36
|
+
"h-7 w-7 rounded-md p-0 [&_[data-icon-root]]:size-3.5 max-md:pointer-coarse:h-9 max-md:pointer-coarse:w-9 max-md:pointer-coarse:[&_[data-icon-root]]:size-5";
|
|
37
|
+
|
|
38
|
+
export const COARSE_POINTER_CHILD_ICON_BUTTON_CLASS =
|
|
39
|
+
"h-8 w-8 justify-center p-0 [&>[data-icon-root]]:size-4 max-md:pointer-coarse:h-9 max-md:pointer-coarse:w-9 max-md:pointer-coarse:[&>[data-icon-root]]:size-5";
|
|
40
|
+
|
|
41
|
+
export const COARSE_POINTER_TOOLBAR_ACTION_BUTTON_CLASS =
|
|
42
|
+
"h-7 rounded-md border-border bg-transparent px-2 text-xs font-medium text-foreground shadow-none hover:bg-state-hover hover:text-foreground max-md:pointer-coarse:h-9";
|
|
43
|
+
|
|
44
|
+
export const COARSE_POINTER_PROMPT_ACTION_BUTTON_CLASS =
|
|
45
|
+
"h-8 px-2 transition-all max-md:pointer-coarse:h-10 max-md:pointer-coarse:px-3";
|
|
46
|
+
|
|
47
|
+
export const COARSE_POINTER_PROMPT_ICON_ACTION_BUTTON_CLASS =
|
|
48
|
+
"size-auto h-8 px-2 transition-all max-md:pointer-coarse:h-10 max-md:pointer-coarse:px-3";
|
|
49
|
+
|
|
50
|
+
export const COARSE_POINTER_PROMPT_COMBO_BUTTON_CLASS =
|
|
51
|
+
"h-8 w-8 rounded-l-none border-l border-l-primary-foreground/20 px-0 transition-all hover:border-l-primary-foreground/30 max-md:pointer-coarse:h-10 max-md:pointer-coarse:w-10";
|
|
52
|
+
|
|
53
|
+
export const COARSE_POINTER_INPUT_HEIGHT_CLASS =
|
|
54
|
+
"h-9 max-md:pointer-coarse:h-10";
|
|
55
|
+
|
|
56
|
+
export const COARSE_POINTER_COMPACT_ROW_HEIGHT_CLASS =
|
|
57
|
+
"h-7 max-md:pointer-coarse:h-9";
|
|
58
|
+
|
|
59
|
+
export const COARSE_POINTER_ROW_HEIGHT_CLASS =
|
|
60
|
+
"h-[var(--bb-sidebar-row-height)] max-md:pointer-coarse:h-[var(--bb-sidebar-row-height-coarse)]";
|
|
61
|
+
|
|
62
|
+
export const COARSE_POINTER_PROVIDER_TAB_SIZE_CLASS =
|
|
63
|
+
"h-7 w-6 max-md:pointer-coarse:h-9 max-md:pointer-coarse:w-9";
|
|
64
|
+
|
|
65
|
+
export const COARSE_POINTER_ROW_ACTION_SIZE_CLASS =
|
|
66
|
+
"h-7 w-7 max-md:pointer-coarse:h-9 max-md:pointer-coarse:w-9";
|