Compare commits

...

111 Commits

Author SHA1 Message Date
Elena Rechkina c0345aaa97 Описание чата с моделями 2025-11-29 00:03:06 +06:00
Elena Rechkina f751a23e65 Концепции 2025-11-28 15:13:15 +06:00
Elena Rechkina 0756141fcc Описание чата с LLM 2025-11-28 15:10:03 +06:00
Elena Rechkina 60c4327897 Описание функции чата с моделями 2025-11-27 17:13:24 +06:00
Elena Rechkina ceb4c272c8 Доработка разделов управление сервисом, обзор сервиса 2025-11-24 16:36:01 +06:00
Левченко Людмила Алексеевна 9332950817 редактирование перехода в чат 2025-11-24 12:32:28 +03:00
Левченко Людмила Алексеевна c4f0202ea2 описание платформы 2025-11-20 15:10:38 +03:00
Elena Rechkina da7acee362 Добавление навигации 2025-11-20 11:59:44 +06:00
Левченко Людмила Алексеевна 1f7d7a5f08 Описание платформы 2025-11-17 14:25:49 +03:00
Левченко Людмила Алексеевна ac94d11c26 Описание разделов Чат и Платформа 2025-11-12 16:10:29 +03:00
Левченко Людмила Алексеевна 46ab890306 Внесение изменений в раздел Быстрый старт 2025-11-12 16:02:56 +03:00
Левченко Людмила Алексеевна 29d9e6e697 Внесение изменений в раздел Быстрый старт 2025-11-12 15:55:12 +03:00
Левченко Людмила Алексеевна 4f98517e1c Удаление structura.md 2025-11-06 14:43:18 +00:00
Левченко Людмила Алексеевна e1e6c53af2 Описание и настройка чата 2025-11-06 17:37:48 +03:00
Левченко Людмила Алексеевна 273fae5567 Описание чата и настройка чата 2025-11-06 17:20:22 +03:00
Левченко Людмила Алексеевна a68d021683 Описание чата и настройка чата 2025-11-06 17:05:13 +03:00
Левченко Людмила Алексеевна 2aa68fc251 Описание чата и настройки 2025-11-06 16:51:16 +03:00
Левченко Людмила Алексеевна 0da343e3a0 Внесение правок в настроки 2025-11-05 15:58:00 +03:00
Левченко Людмила Алексеевна e05518d243 Добавление настроек к платформе 2025-11-05 15:53:55 +03:00
Левченко Людмила Алексеевна 06afb4e637 Добавление документации AI Platform 2025-11-05 15:47:55 +03:00
Elena Rechkina 9d074e416b Добавлен раздел ai 2025-10-23 14:32:11 +06:00
Elena Rechkina 57aaeae566 Правка ссылок 2025-10-14 17:38:51 +06:00
Elena Rechkina ac56186cf7 Правка ссылок 2025-10-14 16:15:19 +06:00
Elena Rechkina f6e295a3f5 Правка ссылок 2025-10-14 16:13:45 +06:00
Речкина Елена Валерьевна 09415adce2 Merge branch 'feature/search-menu#VEGA-5235' into 'main'
VEGA-5236 Адаптация результатов поиска в документации

See merge request common/vega/beecloud-docs!35
2025-10-14 08:06:15 +00:00
Русович Виолетта Игоревна 3609f446cb VEGA-5236 Адаптация результатов поиска в документации 2025-10-14 08:06:15 +00:00
Elena Rechkina 145f0c6702 Правка описания 2025-10-13 22:01:12 +06:00
Elena Rechkina 61947a5acc Правка описания 2025-10-13 21:54:48 +06:00
Речкина Елена Валерьевна 9d638839d6 Merge branch 'feature/vCD' into 'main'
Документация по виртуальным дата-центрам

See merge request common/vega/beecloud-docs!37
2025-10-13 09:27:59 +00:00
Анисин Александр Александрович 39e2370fde Документация по виртуальным дата-центрам 2025-10-13 09:27:59 +00:00
Речкина Елена Валерьевна 1c25d760e2 Merge branch 'feature/start-vm-2' into 'main'
2-start vm 2

See merge request common/vega/beecloud-docs!43
2025-10-06 15:40:37 +00:00
Речкина Елена Валерьевна a869b20d2b 2-start vm 2 2025-10-06 15:40:37 +00:00
Речкина Елена Валерьевна 4e44140183 Merge branch 'feature/start-vm-2' into 'main'
start vm 2

See merge request common/vega/beecloud-docs!42
2025-10-03 10:18:17 +00:00
Речкина Елена Валерьевна 8d36597e0e start vm 2 2025-10-03 10:18:17 +00:00
Elena Rechkina cbca88ec9d version 2025-10-02 21:14:29 +06:00
Elena Rechkina e4d89b5132 Правка ссылки 2025-10-02 21:11:21 +06:00
Речкина Елена Валерьевна 5feef83ae0 Merge branch 'feature/getting-started-vm' into 'main'
Быстрый старт ВМ

See merge request common/vega/beecloud-docs!41
2025-10-02 15:08:06 +00:00
Речкина Елена Валерьевна 123fbb3fb4 Быстрый старт ВМ 2025-10-02 15:08:06 +00:00
Речкина Елена Валерьевна 2021e92467 Edit package.json up version 2025-09-23 09:47:13 +00:00
Речкина Елена Валерьевна 26f4def6c3 Merge branch 'feature/HW' into 'main'
Техническое описание сервисов #VEGA-5488

See merge request common/vega/beecloud-docs!34
2025-09-23 09:42:50 +00:00
Речкина Елена Валерьевна ace0cba558 Техническое описание сервисов #VEGA-5488 2025-09-23 09:42:50 +00:00
Elena Rechkina b669aba0dc правка аннотации 2025-08-25 17:48:56 +06:00
Elena Rechkina 3a20198e52 Правка аннотации к админ. 2025-08-25 17:44:01 +06:00
Elena Rechkina c7e23817d6 Правка навигации, up version 2025-08-25 17:27:58 +06:00
Речкина Елена Валерьевна 8ab527e096 Merge branch 'feature/VEGA-4499-main-page' into 'main'
VEGA-4499: адаптация UI главной страницы документации

Closes VEGA-4499

See merge request common/vega/beecloud-docs!24
2025-08-25 11:21:10 +00:00
Захаров Дмитрий Анатольевич baca55494c VEGA-4499: адаптация UI главной страницы документации 2025-08-25 11:21:09 +00:00
Elena Rechkina 2ce47117e1 Исправлено подключение по ssh 2025-08-22 15:23:17 +06:00
Речкина Елена Валерьевна 398d4cc342 Merge branch 'feature/vm-openstack-flavor' into 'main'
Конфигурации CPU/RAM

See merge request common/vega/beecloud-docs!29
2025-08-22 08:30:38 +00:00
Речкина Елена Валерьевна cbbfc629eb Конфигурации CPU/RAM 2025-08-22 08:30:37 +00:00
Elena Rechkina a8d37525c3 Исправление ошибок 2025-08-22 13:45:59 +06:00
Речкина Елена Валерьевна 08f15a687f Merge branch 'vdc-getting-started' into 'main'
VDC быстрый старт

See merge request common/vega/beecloud-docs!21
2025-08-22 07:44:38 +00:00
Речкина Елена Валерьевна b3ff86ce8b VDC быстрый старт 2025-08-22 07:44:37 +00:00
Elena Rechkina 17eeec3d26 Правка навигации 2025-08-22 13:22:20 +06:00
Elena Rechkina 702c2e01da Убрала верхнее меню 2025-08-22 12:59:56 +06:00
Речкина Елена Валерьевна ff9885c5f8 Merge branch 'feature/header#VEGA-4759' into 'main'
VEGA-4759 Адаптация UI шапки портала документации

See merge request common/vega/beecloud-docs!20
2025-08-22 06:54:17 +00:00
Русович Виолетта Игоревна 021236498e VEGA-4759 Адаптация UI шапки портала документации 2025-08-22 06:54:17 +00:00
Речкина Елена Валерьевна 28e159b8bd Merge branch 'fix/99-right-nav-bar#VEGA-4856' into 'main'
VEGA-4856 Корректировка правого элемента меню

See merge request common/vega/beecloud-docs!28
2025-08-22 06:50:47 +00:00
Русович Виолетта Игоревна 022a3ad303 VEGA-4856 Корректировка правого элемента меню 2025-08-22 06:50:47 +00:00
Речкина Елена Валерьевна 71c9bcb05a Merge branch 'fix/nav-drawer#VEGA-4802' into 'main'
VEGA-4802 Адаптация бокового меню

See merge request common/vega/beecloud-docs!27
2025-08-22 06:45:33 +00:00
Русович Виолетта Игоревна 6b8bccff1d VEGA-4802 Адаптация бокового меню 2025-08-22 06:45:33 +00:00
Речкина Елена Валерьевна ea158a44b0 Merge branch 'feature/vyos-#VEGA-4844' into 'main'
vyos #VEGA-4844

Closes VEGA-4844

See merge request common/vega/beecloud-docs!30
2025-08-21 17:21:44 +00:00
Речкина Елена Валерьевна c140ec8b21 vyos #VEGA-4844 2025-08-21 17:21:44 +00:00
Речкина Елена Валерьевна be581a8757 Merge branch 'feature/VEGA-4499-lists' into 'main'
Исправление стилей списков

See merge request common/vega/beecloud-docs!25
2025-08-06 14:53:46 +00:00
Речкина Елена Валерьевна 285babb9c9 Merge branch 'feature/ssh-path' into 'main'
Подключение по ssh к ВМ

See merge request common/vega/beecloud-docs!23
2025-08-06 14:37:00 +00:00
Речкина Елена Валерьевна fa95157ab7 Подключение по ssh к ВМ 2025-08-06 14:37:00 +00:00
Дмитрий Захаров e208f23363 Исправление стилей списков 2025-08-04 16:46:55 +03:00
Elena Rechkina deab4d3df0 правка ссылки 2025-07-30 19:34:39 +06:00
Речкина Елена Валерьевна 3fffc8d2df Merge branch 'feature/pravki-docs-01.08' into 'main'
Обновление документации-01.08-31.08

See merge request common/vega/beecloud-docs!22
2025-07-30 11:11:02 +00:00
Речкина Елена Валерьевна ff41fe80c4 Обновление документации-01.08-31.08 2025-07-30 11:11:02 +00:00
Бурденко Алексей 17a06a1ed0 Merge branch 'main' of https://git.vimpelcom.ru/common/vega/beecloud-docs 2025-07-28 19:35:04 +03:00
Бурденко Алексей 3262b486cd up version 2025-07-28 19:35:01 +03:00
Elena Rechkina 1b5dc55743 Форматирование 2025-07-28 22:18:37 +06:00
Elena Rechkina 9dfa7a1f51 Добавлены квоты для vdc в тесте 2025-07-28 22:16:08 +06:00
Бурденко Алексей a76020874c up version 2025-07-28 15:46:14 +03:00
Бурденко Алексей a75a69d522 fix type 2025-07-28 15:17:03 +03:00
Elena Rechkina dcbb22232e Опечатки 2025-07-28 17:22:47 +06:00
Elena Rechkina f4ffe76e1d Форматирование 2025-07-28 17:19:31 +06:00
Речкина Елена Валерьевна 186a18ad7c Merge branch 'feature/vmware-cloud-director' into 'main'
Новая структура и оформлениеr

See merge request common/vega/beecloud-docs!19
2025-07-28 11:09:06 +00:00
Речкина Елена Валерьевна 3a116091b1 Новая структура и оформлениеr 2025-07-28 11:09:06 +00:00
Речкина Елена Валерьевна a68ff8d775 Merge branch 'feature/vmware-cloud-director' into 'main'
Вход в cloud director

See merge request common/vega/beecloud-docs!16
2025-07-25 10:48:34 +00:00
Речкина Елена Валерьевна 576ef6a113 Вход в cloud director 2025-07-25 10:48:34 +00:00
Речкина Елена Валерьевна 5cd2b178d4 Merge branch 'feature/design-tokens' into 'main'
Добавление дизайн токенов

See merge request common/vega/beecloud-docs!18
2025-07-24 11:42:47 +00:00
Дмитрий Захаров 91713b08fd Добавление дизайн токенов 2025-07-24 14:10:21 +03:00
Речкина Елена Валерьевна 9c13712c86 Edit index.md 2025-07-05 09:42:06 +00:00
Речкина Елена Валерьевна e6765237a0 Merge branch 'feature/vdc' into 'main'
Feature/vdc

See merge request common/vega/beecloud-docs!15
2025-07-05 09:21:55 +00:00
Речкина Елена Валерьевна 885ea8ffa2 Feature/vdc 2025-07-05 09:21:55 +00:00
Бурденко Алексей b80aa1e4eb Merge branch 'feature/ci' 2025-07-04 14:51:47 +03:00
Речкина Елена Валерьевна bf6dea9f97 Merge branch 'feature/pravki4' into 'main'
Feature/pravki4

See merge request common/vega/beecloud-docs!14
2025-07-04 11:30:54 +00:00
Речкина Елена Валерьевна 4f72f4240b Feature/pravki4 2025-07-04 11:30:54 +00:00
Речкина Елена Валерьевна d0c2366767 Merge branch 'feature/pravki3' into 'main'
Feature/pravki3

See merge request common/vega/beecloud-docs!13
2025-07-04 11:24:56 +00:00
Речкина Елена Валерьевна a9c21a6f1a Feature/pravki3 2025-07-04 11:24:56 +00:00
Речкина Елена Валерьевна badf5ab847 Merge branch 'feature/pravki2' into 'main'
Feature/pravki2

See merge request common/vega/beecloud-docs!12
2025-07-04 11:15:36 +00:00
Речкина Елена Валерьевна 776228dd10 Feature/pravki2 2025-07-04 11:15:36 +00:00
Речкина Елена Валерьевна 7520e5c1f5 Merge branch 'feature/pravki' into 'main'
Feature/pravki

See merge request common/vega/beecloud-docs!11
2025-07-04 11:08:35 +00:00
Речкина Елена Валерьевна f6e58a0858 Feature/pravki 2025-07-04 11:08:35 +00:00
Речкина Елена Валерьевна ac4fb708e5 Merge branch 'feature/VEGA-4655-structura' into 'main'
Структура документации BC -  #VEGA-4655

Closes VEGA-4655

See merge request common/vega/beecloud-docs!9
2025-07-04 10:57:57 +00:00
Речкина Елена Валерьевна 7b466745d2 Структура документации BC - #VEGA-4655 2025-07-04 10:57:57 +00:00
Бурденко Алексей 187d3f28c1 up 2025-06-25 11:11:59 +03:00
Бурденко Алексей 2cc76be5bc up 2025-06-25 11:02:21 +03:00
Бурденко Алексей 71fce139c4 test 2025-06-25 10:56:25 +03:00
Бурденко Алексей 93a42e2089 up 2025-06-25 10:51:17 +03:00
Бурденко Алексей e47551628a up 2025-06-24 17:17:54 +03:00
Бурденко Алексей 77b961a79a up 2025-06-24 17:01:18 +03:00
Бурденко Алексей c37a779ab6 up 2025-06-24 14:44:18 +03:00
Бурденко Алексей b97ea8c667 test 2025-06-24 14:37:02 +03:00
Бурденко Алексей 0b72328bd1 check 2025-06-24 14:25:28 +03:00
Бурденко Алексей 1a640f2411 up 2025-06-24 11:57:38 +03:00
Бурденко Алексей f7a36d9563 up 2025-06-24 11:50:04 +03:00
Бурденко Алексей df50c65b6e up 2025-06-24 11:45:29 +03:00
Бурденко Алексей 0f07e8291e up 2025-06-24 10:45:56 +03:00
Бурденко Алексей 1ec2f3f4df up 2025-06-24 10:41:09 +03:00
635 changed files with 6712 additions and 9984 deletions
+4
View File
@@ -14,3 +14,7 @@ src/.vuepress/.cache
src/.vuepress/.temp
src/.vitepress/cache
packages-list.json
/.vale
/.vscode
/.vale.ini
/VimpelcomCAG2.pem
+5 -3
View File
@@ -5,10 +5,12 @@ stages:
variables:
DIST_DIR: "./src/.vitepress/dist"
DMZ_DIST_DIR: "./dmz-dist"
CONTAINER_REGISTRY: harbor.vimpelcom.ru
PRODUCT_PROD: vega/beecloud
IMAGE_NAME: docs
PRODUCT_DMZ: vega/beecloud/dmz
IMAGE_NAME: docs-portal
include:
- ci/develop.yml
- "ci/rules.yml"
- ci/*.yml
- "ci/deploy/*.inc.yml"
+2
View File
@@ -1 +1,3 @@
cafile=VimpelcomCAG2.pem
@beeline:registry=https://nexus.vimpelcom.ru/repository/npm-all/
registry=https://nexus.vimpelcom.ru/repository/npm-all/
+1 -1
View File
@@ -1 +1 @@
0.0.1
0.0.2-fix1
+59
View File
@@ -0,0 +1,59 @@
-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgIQQaIoxfL+KLhIxGpv9/PUMzANBgkqhkiG9w0BAQsFADBN
MRIwEAYKCZImiZPyLGQBGRYCcnUxGTAXBgoJkiaJk/IsZAEZFgl2aW1wZWxjb20x
HDAaBgNVBAMTE1ZpbXBlbGNvbSBSb290Q0EgRzIwHhcNMTgxMTIxMDkzMjE5WhcN
MzgxMTIxMDk0MjE5WjBNMRIwEAYKCZImiZPyLGQBGRYCcnUxGTAXBgoJkiaJk/Is
ZAEZFgl2aW1wZWxjb20xHDAaBgNVBAMTE1ZpbXBlbGNvbSBSb290Q0EgRzIwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD7q+kJ4RNskizo7aNgVoAt9Z/p
tcmjjcuH5iP/5MHLKN8eeWJWxwNm21tevwlIBGXWAvx43v4+xe77IELZdz3RErtA
W1UYfdzI+c9eYyy9OORc5PgmcWDV2eWuVMFWFnkXbAX0evBM8FPzXie1n393vaT3
BDmNuoiiuupq/uYY3z5iFVZBpLMZyBxrxYr5adq1oefbfMBeGJGT8N3sqIw1Jzt7
TsUoYSgpgzSbMY7wbOY8yOcRb0NI1iWo3Rky5DBkyWBm4pvaIe2cXPq7gbXCSFRi
ewP68+c2b4NTX091paEC542yb9KhKLBfTtcnZPbHAHOABtubhEwf9HfMsehlAgMB
AAGjUTBPMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTv
4MjZ3yyuntT6y3fR60JeZm6wTjAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0B
AQsFAAOCAQEApdVkNkRUMuu6p5hq32NdXkgHPTYKKdaxs+c2jEoB3giYrQFIfto+
UVNPg3IE2iAlpxccRw0jyJ2neC/ai1Imgg6xCZ3a3RYFjoh5eaJWN/aSI8/pg1E8
MDpzCCJGdo0Ei8zC2eDA8buSrbBtjDN8c//3X9/VhXkZzs3dL7jaIIxSR+EHXWH0
3al6AavaN/X68qrRWHs2FBpw6qaecL8BPJiliaD3Rl1RyucTUibbUD6ryqeTgMrP
aeaCPa0Ypb6pw7y0nLyJJPmsX9kgcgS0oEL6RsxhpjZ0eQZcRome/pV9BPUDJyLT
z8mBO6VYVh9DcuqPmnBxgucMc6mjJiRIEg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIGqTCCBZGgAwIBAgITcgAAAAI2SdIO0pgfxQAAAAAAAjANBgkqhkiG9w0BAQsF
ADBNMRIwEAYKCZImiZPyLGQBGRYCcnUxGTAXBgoJkiaJk/IsZAEZFgl2aW1wZWxj
b20xHDAaBgNVBAMTE1ZpbXBlbGNvbSBSb290Q0EgRzIwHhcNMTgxMTI2MTAzNzUw
WhcNMjgxMTI2MTA0NzUwWjBmMRIwEAYKCZImiZPyLGQBGRYCcnUxGTAXBgoJkiaJ
k/IsZAEZFgl2aW1wZWxjb20xEzARBgoJkiaJk/IsZAEZFgNiZWUxIDAeBgNVBAMT
F1ZpbXBlbGNvbSBJbnRlcm5hbENBIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA2uD2VDoEA25or20KxFS1fWZMIo1M61+WCwHE1kXZVJulbxOxMkEl
1m8urNyvXkAbU9Gd+nZ6ZPSMkI9lx0ki9EPK5uaBxRY4FDACaT1sEjo+d/ZYMyBB
P/s4VxIaISbqvD8/MH/h6N5e5eIgAnfqtyblEBKNUuJEDJAirIUb/VnjH7f8gvI/
CqHa8KOSC/TE2ZqctlJRrm7mRJwwDHrL/VewC7LtwJD7bcWDHNc5+psJLmKc9R9R
VREi5TfRKD8Mlr0syqmJxqzElfGOusUGSLJqpHS4LUlPrwXjoZ0ZMvWE5U3vftMX
dHCCVmtB6R+O1iGaM6sK1jnliU8K8NssMwIDAQABo4IDZzCCA2MwEAYJKwYBBAGC
NxUBBAMCAQAwHQYDVR0OBBYEFEhtK6bKwldIiW8e/DlSWntIC19xMBkGCSsGAQQB
gjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/
MB8GA1UdIwQYMBaAFO/gyNnfLK6e1PrLd9HrQl5mbrBOMIIBZwYDVR0fBIIBXjCC
AVowggFWoIIBUqCCAU6GgcZsZGFwOi8vL0NOPVZpbXBlbGNvbSUyMFJvb3RDQSUy
MEcyLENOPVZpbXBlbFJvb3RDQUcyLENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBT
ZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPXZpbXBlbGNv
bSxEQz1ydT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xh
c3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnSGRWh0dHA6Ly9wa2lpbnQuYmVlLnZpbXBl
bGNvbS5ydS9DZXJ0RW5yb2xsL1ZpbXBlbGNvbSUyMFJvb3RDQSUyMEcyLmNybIY8
aHR0cDovL3BraWV4dC5iZWVsaW5lLnJ1L3BraS9jZHAvVmltcGVsY29tJTIwUm9v
dENBJTIwRzIuY3JsMIIBaQYIKwYBBQUHAQEEggFbMIIBVzCBtwYIKwYBBQUHMAKG
gapsZGFwOi8vL0NOPVZpbXBlbGNvbSUyMFJvb3RDQSUyMEcyLENOPUFJQSxDTj1Q
dWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0
aW9uLERDPXZpbXBlbGNvbSxEQz1ydT9jQUNlcnRpZmljYXRlP2Jhc2U/b2JqZWN0
Q2xhc3M9Y2VydGlmaWNhdGlvbkF1dGhvcml0eTBRBggrBgEFBQcwAoZFaHR0cDov
L3BraWludC5iZWUudmltcGVsY29tLnJ1L0NlcnRFbnJvbGwvVmltcGVsY29tJTIw
Um9vdENBJTIwRzIuY3J0MEgGCCsGAQUFBzAChjxodHRwOi8vcGtpZXh0LmJlZWxp
bmUucnUvcGtpL2FpYS9WaW1wZWxjb20lMjBSb290Q0ElMjBHMi5jcnQwDQYJKoZI
hvcNAQELBQADggEBAHMJHkHITBOqVf2nbsnWveBmZHEjYogxOxNLYezU5f6ySnJl
ySDz62n7tueq5PFyAPWI4gtDN0K0zdZALCR9CmOT3vf65Wx7HWNU44jBD1slncMi
rAVkaQW7UcMiB4FWTJMq6B9ozVel6KHkTp96wOGahwaAZgF9g3YtEgZXmrnYaMtw
g5cjruQ/XAQopeu+47g13kbHTzH1eKaX4rqZI/YHbO5Sv4lX179LjT08qmTx2dc6
SUyJloalYAK0Spgza8JhEnHPTmwRB6zcZ+PifgkTZVGbx7krsmUyegr53Nlj9hFd
g5VD1UoDfvcTmkzvdKMVEFfKM7299m0d264YnuM=
-----END CERTIFICATE-----
+5 -28
View File
@@ -1,30 +1,4 @@
develop:npm:
image: harbor.vimpelcom.ru/dockerhub/library/node:lts
stage: build
cache:
- key:
files:
- package.json
paths:
- node_modules/
rules:
- !reference [.build-npm-rules, rules]
variables:
PRODUCT: "$PRODUCT_PROD"
script:
- export PRODUCT_VERSION=$(node -p "require('./package.json').version")
- echo PRODUCT_VERSION="$PRODUCT_VERSION" >> .env
- echo PRODUCT="$PRODUCT_PROD" >> .env
- npm install
- npm run build
artifacts:
paths:
- "$DIST_DIR"
reports:
dotenv: .env
expire_in: 1h
develop-image:
build-image:
image: harbor.vimpelcom.ru/dockerhub/library/docker:20.10.11-dind
stage: package
rules:
@@ -38,8 +12,11 @@ develop-image:
- docker build --build-arg DIST_DIR=${DIST_DIR} -f ./build.Dockerfile -t ${CONTAINER_REGISTRY}/${PRODUCT}/${IMAGE_NAME}:$PRODUCT_VERSION -t ${CONTAINER_REGISTRY}/${PRODUCT}/${IMAGE_NAME}:latest .
- docker push ${CONTAINER_REGISTRY}/${PRODUCT}/${IMAGE_NAME}:$PRODUCT_VERSION
- docker push ${CONTAINER_REGISTRY}/${PRODUCT}/${IMAGE_NAME}:latest
- docker build --build-arg DIST_DIR=${DMZ_DIST_DIR} --build-arg WROOT_DIR="/usr/share/nginx/html" -f ./build.Dockerfile -t ${CONTAINER_REGISTRY}/${PRODUCT_DMZ}/${IMAGE_NAME}:$PRODUCT_VERSION -t ${CONTAINER_REGISTRY}/${PRODUCT_DMZ}/${IMAGE_NAME}:latest .
- docker push ${CONTAINER_REGISTRY}/${PRODUCT_DMZ}/${IMAGE_NAME}:$PRODUCT_VERSION
- docker push ${CONTAINER_REGISTRY}/${PRODUCT_DMZ}/${IMAGE_NAME}:latest
needs:
- job: develop:npm
- job: build:npm
artifacts: true
optional: true
artifacts:
+29
View File
@@ -0,0 +1,29 @@
build:npm:
image: harbor.vimpelcom.ru/dockerhub/library/node:lts
stage: build
cache:
- key:
files:
- package.json
paths:
- node_modules/
rules:
- !reference [.build-npm-rules, rules]
variables:
PRODUCT: "$PRODUCT_PROD"
script:
- export PRODUCT_VERSION=$(node -p "require('./package.json').version")
- echo PRODUCT_VERSION="$PRODUCT_VERSION" >> .env
- echo PRODUCT="$PRODUCT_PROD" >> .env
- npm install
- npm run build
- export VITE_NEW_VERSION="true"
- echo "$DMZ_DIST_DIR"
- ./node_modules/.bin/vitepress build src --outDir "$DMZ_DIST_DIR"
artifacts:
paths:
- "$DIST_DIR"
- "$DMZ_DIST_DIR"
reports:
dotenv: .env
expire_in: 1h
+39
View File
@@ -0,0 +1,39 @@
deploy-test-stand:
stage: deploy
image: harbor.vimpelcom.ru/dockerhub/library/alpine:3.21.2
variables:
stand: cloud-stand.vega-dev.cloud.vimpelcom.ru
rules:
- if: $CI_COMMIT_BRANCH && $CI_PIPELINE_SOURCE == "merge_request_event"
when: never
- if: $CI_PIPELINE_SOURCE == "push"
when: manual
before_script:
- |
sed -i s%https://dl-cdn.alpinelinux.org/%http://rhrepo.vimpelcom.ru/ext/ya/mirrors/% /etc/apk/repositories && \
apk --no-cache add tzdata ca-certificates curl openssh-client yq jq && \
rm -rf /var/cache/apk/*
- which ssh-agent || (apt-get update -y && apt-get install openssh-client -y)
- eval $(ssh-agent -s)
- mkdir -p ~/.ssh
- echo -n "$TECH_SSH_KEY" | tr -d '\r' > ~/.ssh/id_rsa
- chmod 700 ~/.ssh
- chmod 600 ~/.ssh/id_rsa
- >
echo "stand: ${stand}"
ssh-keyscan "${stand}" >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
script:
- >
echo -e "Connect to ${stand}..." &&
scp -o StrictHostKeyChecking=no ci/deploy/deploy.sh "dorootless@${stand}:~/deploy.sh" &&
ssh "dorootless@${stand}" "export CONTAINER_REGISTRY=$CONTAINER_REGISTRY &&
export PRODUCT=$PRODUCT &&
export PRODUCT_VERSION=$PRODUCT_VERSION &&
export IMAGE_NAME=$IMAGE_NAME &&
chmod 700 ~/deploy.sh &&
~/deploy.sh ${IMAGE_NAME} &&
rm -f ~/deploy.sh"
needs:
- job: build-image
optional: true
+73
View File
@@ -0,0 +1,73 @@
# echo -e # ключ -e в комманде echo включает отображение "backslash escapes"; например \n - переход на следующую строку, \t -табуляция
# echo -n # ключ -n в команде echo сигнализирует, что после вывода информации не нужно переходить на следующую строку.
# - > переносы строк удаляются
# - | переносы строк не удаляются
# Git add
# - git submodule add -b main https://gitlab-ci-token:${CI_JOB_TOKEN}@$CI_SERVER_URL/products/vega/infra
# - git submodule sync --recursive
# - git submodule update --init --recursive
# # Прокидываем name + email, чтобы gitlab не сыпал ошибки
# - git config --global user.name "YourName"
# - git config --global user.email "YourEmail"
# # Вызываем наш скрипт, который инкрементирует версию
# - node bumpVersion.js
# # Добавляем и пушим наши изменения в ветку откуда стригерился pipeline
# - git add ./package.json
# - git commit -m "bump package.json version"
# # Используем опцию gitlab -o ci.skip, для того, чтобы наш коммит не тригерил новый pipeline
# - git push origin HEAD:$CI_COMMIT_REF_NAME -o ci.skip
.deploy-template:
image: harbor.vimpelcom.ru/dockerhub/library/alpine:3.21.2
before_script:
- |
sed -i s%https://dl-cdn.alpinelinux.org/%http://rhrepo.vimpelcom.ru/ext/ya/mirrors/% /etc/apk/repositories && \
apk --no-cache add tzdata ca-certificates curl openssh-client yq jq && \
rm -rf /var/cache/apk/*
- which ssh-agent || (apt-get update -y && apt-get install openssh-client -y)
- eval $(ssh-agent -s)
- mkdir -p ~/.ssh
- echo -n "$TECH_SSH_KEY" | tr -d '\r' > ~/.ssh/id_rsa
- chmod 700 ~/.ssh
- chmod 600 ~/.ssh/id_rsa
# https://mikefarah.gitbook.io/yq/operators/traverse-read#nested-special-characters
- STANDS=$(echo "$STANDS" | yq '."'"${CI_COMMIT_REF_NAME}"'".[]')
- RED=$'\033[0;31m'
- RESET=$'\033[0m'
- >
if [[ -z "$STANDS" ]]; then
echo -e "${RED}STANDS for ${CI_COMMIT_REF_NAME:=CI_COMMIT_REF_NAME} is null${RESET}"
exit 1
fi
- >
for stand in $STANDS; do
echo "stand: ${stand}"
ssh-keyscan "${stand}" >> ~/.ssh/known_hosts
done
- chmod 644 ~/.ssh/known_hosts
# Если получилось что-то пустое
- >
if [[ -z "$APPVERSION" ]]; then
APPVERSION="0.0.1"
fi
script:
- >
for stand in $STANDS; do
echo -e "Connect to ${stand}..." &&
scp -o StrictHostKeyChecking=no ci/deploy/deploy.sh "dorootless@${stand}:~/deploy.sh" &&
ssh "dorootless@${stand}" "export CONTAINER_REGISTRY=$CONTAINER_REGISTRY &&
export PRODUCT=$PRODUCT &&
export PRODUCT_VERSION=$PRODUCT_VERSION &&
export IMAGE_NAME=$IMAGE_NAME &&
chmod 700 ~/deploy.sh &&
~/deploy.sh ${IMAGE_NAME} &&
rm -f ~/deploy.sh"
done
needs:
- job: build-image
optional: true
+56
View File
@@ -0,0 +1,56 @@
#!/bin/bash
# CONTAINER_REGISTRY="harbor.vimpelcom.ru"
# PRODUCT="vega/stage"
# PRODUCT_VERSION="0.5.3"
if [[ $# -eq 0 ]] ; then
echo "No arguments supplied"
exit 1
fi
if [[ -z "$1" ]] ; then
echo "No argument CONTAINER_NAME"
exit 1
fi
GREEN=$'\033[0;32m'
RED=$'\033[0;31m'
BLUE=$'\033[0;36m'
WHITE=$'\033[0;37m'
RESET=$'\033[0m'
CONTAINER_NAME=${1}
IMAGE_URL="$CONTAINER_REGISTRY/$PRODUCT/$IMAGE_NAME:$PRODUCT_VERSION"
DOCKER_COMPOSE_EXEC="docker-compose"
echo -e "${GREEN}IMAGE_URL${RESET}: ${IMAGE_URL}"
if ! [ -x "$(command -v docker-compose)" ]; then
DOCKER_COMPOSE_EXEC="docker compose"
fi
# для -z необходимо указывать параметры в двойных ковычках
if [ -z "$(docker ps -aq -f name=^${CONTAINER_NAME}$)" ]; then
echo -e "${RED}${CONTAINER_NAME:-container} not running.${RESET}"
exit 1
fi
COMPOSE_FILE="$(docker inspect --format '{{index .Config.Labels "com.docker.compose.project.config_files"}}' $CONTAINER_NAME | tr , \\n | xargs grep -wH $IMAGE_NAME | cut -d: -sf1 | uniq)"
COMPOSE_ALL_FILES="-f $COMPOSE_FILE"
cp $COMPOSE_FILE "$COMPOSE_FILE.orig"
# sed -i '/image: .*'$IMAGE_NAME'/ s|:.*|: '"$IMAGE_URL"'|' $COMPOSE_FILE
sed -r -i '/image: .*'$IMAGE_NAME'(:|@|$)/ s|:.*|: '"$IMAGE_URL"'|' $COMPOSE_FILE
if [ -e ~dorootless/docker-compose-svc.yaml ]; then
COMPOSE_SVC_FILE=~dorootless/docker-compose-svc.yaml
COMPOSE_ALL_FILES="-f $COMPOSE_SVC_FILE -f $COMPOSE_FILE"
fi
$DOCKER_COMPOSE_EXEC $COMPOSE_ALL_FILES pull $CONTAINER_NAME
$DOCKER_COMPOSE_EXEC $COMPOSE_ALL_FILES up -d
if [ "$(docker ps -a -q -f name=ingress)" ]; then
$DOCKER_COMPOSE_EXEC $COMPOSE_ALL_FILES exec ingress angie -s reload
fi
+1 -4
View File
@@ -2,7 +2,4 @@
rules:
- if: $CI_COMMIT_BRANCH && $CI_PIPELINE_SOURCE == "merge_request_event"
when: never
- if: $CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "feature/ci")
exists:
- .npmrc
- ./*/.npmrc
- if: $CI_PIPELINE_SOURCE == "push"
+28 -2
View File
@@ -1,14 +1,15 @@
{
"name": "docs",
"version": "0.5.0",
"version": "0.6.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "docs",
"version": "0.5.0",
"version": "0.6.2",
"license": "MIT",
"dependencies": {
"@beeline/design-tokens": "^1.31.0",
"vue": "3.4.7"
},
"devDependencies": {
@@ -16,6 +17,7 @@
"@types/node": "20.10.7",
"@vitejs/plugin-vue": "4.3.4",
"sass": "1.69.7",
"typescript": "^5.8.3",
"vitepress": "1.0.0-rc.40",
"vitepress-plugin-tabs": "0.5.0"
}
@@ -244,6 +246,16 @@
"node": ">=6.0.0"
}
},
"node_modules/@beeline/design-tokens": {
"version": "1.31.0",
"resolved": "https://nexus.vimpelcom.ru/repository/npm-all/@beeline/design-tokens/-/design-tokens-1.31.0.tgz",
"integrity": "sha512-sTyldwSkjvrpXuORcIfwjWD9Kmw5odEKB96UvCGv0uxYY5pIFsbnJodPE+DyuKh/eHg0aNsWl2DzEHii13kLqQ==",
"hasInstallScript": true,
"license": "ISC",
"bin": {
"ds-migrate": "migrator/migrator.js"
}
},
"node_modules/@docsearch/css": {
"version": "3.3.0",
"resolved": "https://nexus.vimpelcom.ru/repository/npm-all/@docsearch/css/-/css-3.3.0.tgz",
@@ -1768,6 +1780,20 @@
"node": ">=8.0"
}
},
"node_modules/typescript": {
"version": "5.8.3",
"resolved": "https://nexus.vimpelcom.ru/repository/npm-all/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"devOptional": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://nexus.vimpelcom.ru/repository/npm-all/undici-types/-/undici-types-5.26.5.tgz",
+6 -4
View File
@@ -1,7 +1,7 @@
{
"name": "docs",
"version": "0.5.0",
"description": "Vega docs portal",
"version": "0.6.4",
"description": "Beeline Cloud docs",
"main": "index.js",
"scripts": {
"dev": "vitepress dev src",
@@ -15,14 +15,16 @@
},
"license": "MIT",
"dependencies": {
"@beeline/design-tokens": "^1.31.0",
"vue": "3.4.7"
},
"devDependencies": {
"@docsearch/css": "3.3.0",
"@types/node": "20.10.7",
"@vitejs/plugin-vue": "4.3.4",
"sass": "1.69.7",
"typescript": "^5.8.3",
"vitepress": "1.0.0-rc.40",
"vitepress-plugin-tabs": "0.5.0",
"@vitejs/plugin-vue": "4.3.4"
"vitepress-plugin-tabs": "0.5.0"
}
}
+22
View File
@@ -0,0 +1,22 @@
#ps
# Configs
$Env:CONTAINER_REGISTRY = "harbor.vimpelcom.ru"
$Env:PRODUCT = "vega/cloud"
$Env:IMAGE_NAME = "docs"
$Env:PRODUCT_VERSION = "0.6.2" # node -p "require('./package.json').version"
$Env:PKG_NAME = "vega-portal" # node -p "require('./package.json').name"
# VITE VARS
Remove-Item -Recurse -Force dist
# Write-Output "Version: " node -p "require('./package.json').version"
git pull
Write-Output " Компиляция:" $env:PKG_NAME'@'$env:PRODUCT_VERSION
npm install
npm run build
docker build -f ./build.Dockerfile -t $env:CONTAINER_REGISTRY/$env:PRODUCT/$env:IMAGE_NAME':'$env:PRODUCT_VERSION .
docker image list | FINDSTR "$env:PRODUCT/$env:IMAGE_NAME"
docker push $env:CONTAINER_REGISTRY/$env:PRODUCT/$env:IMAGE_NAME':'$env:PRODUCT_VERSION
+173 -398
View File
@@ -42,9 +42,10 @@ console.log({ base: typeof new_version !== 'undefined' ? '/' : '/docs/' })
// https://vitepress.dev/reference/site-config
export default defineConfig({
title: "BeeCloud Docs",
description: "Документация публичного облака",
head: [['link', { rel: 'icon', href: '/favicon.svg' }]],
srcDir: ".",
title: "cloud",
description: "Документация Beeline Cloud",
head: [['link', { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/bee-favicon.png' }]],
base: typeof new_version !== 'undefined' ? '/' : '/docs/',
markdown: {
config(md) {
@@ -63,7 +64,11 @@ export default defineConfig({
}
},
themeConfig: {
logo: '/favicon.svg',
logo: {
light: '/logo-light-theme.svg',
dark: '/logo-dark-theme.svg',
alt: 'cloud',
},
search: {
provider: 'local',
options: {
@@ -75,7 +80,7 @@ export default defineConfig({
buttonAriaLabel: 'Поиск'
},
modal: {
noResultsText: 'Нет результатов для',
noResultsText: 'Не удалось загрузить данные',
resetButtonTitle: 'Сбросить',
displayDetails: 'Показать расширенный список',
footer: {
@@ -90,412 +95,182 @@ export default defineConfig({
}
},
// https://vitepress.dev/reference/default-theme-config
nav: [
{
text: 'Документация',
link: '/guide/',
},
// {
// text: 'Wiki-DF',
// link: '/wikidf/',
// },
{
text: 'Terraform',
link: '/terraform/',
},
{
text: 'Консоль управления',
link: 'https://console.cloud.dfcloud.ru'
}
],
// socialLinks: [
// { icon: { svg: gitlab }, link: 'https://git.vimpelcom.ru/common/vega/docs' }
// ],
// editLink: {
// pattern: 'https://git.vimpelcom.ru/-/ide/project/common/vega/docs/edit/develop/-/src/:path',
// text: 'Отредактируйте эту страницу на GitLab'
// },
// nav: [
// {
// text: 'Документация',
// link: '/guide/',
// },
// {
// text: 'API',
// link: '',
// },
// {
// text: 'Terraform',
// // link: '/terraform/',
// link: '',
// },
// ],
docFooter: {
next: 'Вперед',
prev: 'Назад'
},
lastUpdated: {
text: 'Обновлена',
formatOptions: {
dateStyle: 'long',
}
},
outline: {
label: 'Содержание'
},
sidebar: {
'/guide/': [
{
text: 'Облачные вычисления',
collapsed: true,
'/platform/': [
{
text: 'Платформа Beeline Cloud', link: '/platform/index.md',
collapsed: true,
items: [
{ text: 'Обзор сервиса', link: '/guide/compute/compute-overview.md' },
{ text: 'Быстрый старт', link: '/guide/compute/compute-getting-started.md' },
{ text: 'Виртуальные серверы', link: '/guide/compute/compute-instructions/compute-servers-create.md' },
{ text: 'Управление виртуальными серверами', link: '/guide/compute/compute-instructions/compute-servers-manage.md' },
{ text: 'Диски', link: '/guide/compute/compute-instructions/compute-disks.md' },
{ text: 'Группы размещения', link: '/guide/compute/compute-instructions/compute-affinity.md' },
{ text: 'IP-адрес', link: '/guide/compute/compute-instructions/compute-ip.md' },
{ text: 'Квоты и лимиты', link: '/guide/compute/compute-limits.md' },
{ text: 'Уровень обслуживания', link: '/guide/compute/compute-ola.md' },
]
},
{
text: 'Объектное хранилище',
collapsed: true,
items: [
{ text: 'Обзор сервиса', link: '/guide/storage/storage-overview.md' },
{
text: 'Подключение к хранилищу',
collapsed: true,
items: [
{ text: 'WinSCP', link: '/guide/storage/storage-instructions/s3-connect/winscp.md' },
{ text: 'S3cmd', link: '/guide/storage/storage-instructions/s3-connect/s3cmd.md' },
]
},
{ text: 'Управление хранилищем', link: '/guide/storage/storage-instructions/storage-s3.md' },
{ text: 'Квоты и лимиты', link: '/guide/storage/storage-limits.md' },
{ text: 'Уровень обслуживания', link: '/guide/storage/storage-ola.md' },
]
},
{
text: 'DNS',
collapsed: true,
items: [
{ text: 'Обзор сервиса', link: '/guide/dns/dns-overview.md' },
{ text: 'Ресурсные записи', link: '/guide/dns/dns-instructions/dns-create.md' },
{ text: 'Квоты и лимиты', link: '/guide/dns/dns-limits.md' },
]
},
{
text: 'Аккаунт',
collapsed: true,
items: [
{ text: 'Проекты', link: '/guide/admin/projects.md' },
{ text: 'Ролевая модель', link: '/guide/admin/roles.md' },
{ text: 'Квоты и лимиты', link: '/guide/admin/limits.md' },
{ text: 'Регионы', link: '/guide/admin/availability-matrix.md' },
{ text: 'SSH ключи', link: '/guide/admin/ssh.md' },
{ text: 'Участники проекта', link: '/guide/admin/users.md' },
]
},
{
text: 'Wiki DF',
collapsed: true,
items: [
{
text: 'Cертификаты и лицензии beeline cloud',
collapsed: true,
items: [
{ text: 'Лицензии', link: '/guide/wikidf/01-lic-sert/lic.md' },
{ text: 'Cертификаты', link: '/guide/wikidf/01-lic-sert/sert.md' },
]
},
{ text: 'База знаний beeline cloud', link: '/guide/wikidf/02-kb/02-kb-overview.md' },
{
text: 'Инфраструктурные сервисы',
collapsed: true,
items: [
{ text: 'Инфраструктурные сервисы - Обзор', link: '/guide/wikidf/03-iaas/03-0-iaas-overview.md' },
{
text: 'BeeCloud Stack',
collapsed: true,
items: [
{ text: 'BeeCloud Stack - Обзор сервиса', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-0-stack-overview.md' },
{ text: '1. Архитектура сервиса', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-1.md' },
{ text: '2. Роли и авторизация', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-2.md' },
{
text: '3. Инструкция',
collapsed: true,
items: [
{
text: 'Вычисления',
collapsed: true,
items: [
{ text: 'A. Создание ВМ', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-1/03-1-3-1-a.md' },
{ text: 'B. Старт, стоп и рестарт ВМ', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-1/03-1-3-1-b.md' },
{ text: 'C. Модификация ВМ', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-1/03-1-3-1-c.md' },
{ text: 'D. Создание, удаление и откат к снимку ВМ', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-1/03-1-3-1-d.md' },
{ text: 'E. Доступ к консоли ВМ', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-1/03-1-3-1-e.md' },
{ text: 'F. Использование носителя для восстановления ВМ', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-1/03-1-3-1-f.md' },
{ text: 'G. Удаление ВМ', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-1/03-1-3-1-g.md' },
{ text: 'H. Cдувание ОЗУ гостевой ОС ВМ', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-1/03-1-3-1-h.md' },
{ text: 'I. Просмотр истории ВМ', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-1/03-1-3-1-i.md' },
]
},
{
text: 'Программно-определяемый маршрутизатор (Edge)',
collapsed: true,
items: [
{ text: 'Edge - Обзор', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-0-overview.md' },
{ text: 'A. Создание роутера', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-a.md' },
{ text: 'B. Удаление роутера', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-b.md' },
{ text: 'C. Старт, стоп и рестарт роутера', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-c.md' },
{ text: 'D. Добавление правил фаервола', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-d.md' },
{ text: 'E. Удаление правил фаервола', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-e.md' },
{ text: 'F. Добавление правил NAT', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-f.md' },
{ text: 'G. Добавление виртуального сетевого порта', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-g.md' },
{ text: 'H. Получение отчета о работе маршрутизатора', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-h.md' },
]
},
{
text: 'Сети',
collapsed: true,
items: [
{ text: 'Edge - Обзор', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-0-overview.md' },
{ text: 'A. Создание роутера', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-a.md' },
{ text: 'B. Удаление роутера', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-b.md' },
{ text: 'C. Старт, стоп и рестарт роутера', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-c.md' },
{ text: 'D. Добавление правил фаервола', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-d.md' },
{ text: 'E. Удаление правил фаервола', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-e.md' },
{ text: 'F. Добавление правил NAT', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-f.md' },
{ text: 'G. Добавление виртуального сетевого порта', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-g.md' },
{ text: 'H. Получение отчета о работе маршрутизатора', link: '/guide/wikidf/03-iaas/03-1-stack/03-1-3/03-1-3-2/03-1-3-2-h.md' },
]
},
]
},
]
},
{
text: 'Cloud Compute',
collapsed: true,
items: [
{ text: 'Cloud Compute - Назначение сервиса', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-0-cc-overview.md' },
{
text: '1. Описание сервиса',
collapsed: true,
items: [
{ text: '01. Состав сервиса', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-1/03-2-1-1.md' },
{
text: '02. Техническое описание сервиса',
collapsed: true,
items: [
{ text: 'Техническое описание сервиса', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-1/03-2-1-2/03-2-1-2-0-overview.md' },
{ text: 'A. Cloud Compute Metrocluster', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-1/03-2-1-2/03-2-1-2-1.md' },
]
},
{ text: '03. Основные функциональные возможности', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-1/03-2-1-3.md' },
{ text: '04. Дополнительные возможности', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-1/03-2-1-4.md' },
{ text: '05. Основные опции', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-1/03-2-1-5.md' },
{ text: '06. Хранение данных сервиса', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-1/03-2-1-6.md' },
{ text: '07. Регионы доступности сервиса', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-1/03-2-1-7.md' },
{ text: '08. Подключение Terraform к VCD', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-1/03-2-1-8.md' },
]
},
{ text: '2. Соответствие сервиса требованиям и стандартам безопасности сервиса', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-2.md' },
{ text: '3. Порядок подключения и зоны ответственности', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-3.md' },
{ text: '4. Тарификация и модели оплаты', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-4.md' },
{
text: '5. Инструкция по настройке Distributed Firewall (DFW)',
collapsed: true,
items: [
{ text: 'Инструкция по настройке DFW', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-5/03-2-5-0-overview.md' },
{ text: 'A. Добавление DFW в DCG', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-5/03-2-5-1.md' },
{ text: 'B. Дополнительные настройки', link: '/guide/wikidf/03-iaas/03-2-cloud-compute/03-2-5/03-2-5-2.md' },
]
},
]
},
{
text: 'Аварийное восстановление (Disaster Recovery)',
collapsed: true,
items: [
{ text: 'Аварийное восстановление (Disaster Recovery) - Назначение сервиса', link: '/guide/wikidf/03-iaas/03-3-recovery/03-3-0-overview.md' },
{ text: 'DRaaS', link: '/guide/wikidf/03-iaas/03-3-recovery/03-3-1.md' },
{ text: 'Репликация ВМ', link: '/guide/wikidf/03-iaas/03-3-recovery/03-3-2.md' },
]
},
{
text: 'Миграция виртуальных машин',
collapsed: true,
items: [
{ text: 'Миграция виртуальных машин - Назначение сервиса', link: '/guide/wikidf/03-iaas/03-4-migration/03-4-0-overview.md' },
{ text: '1. Состав сервиса', link: '/guide/wikidf/03-iaas/03-4-migration/03-4-1.md' },
{ text: '2. Порядок предоставления сервиса. Зоны ответственности', link: '/guide/wikidf/03-iaas/03-4-migration/03-4-2.md' },
{ text: '3. Тарификация сервиса', link: '/guide/wikidf/03-iaas/03-4-migration/03-4-3.md' },
]
},
{
text: 'Резервное копирование',
collapsed: true,
items: [
{ text: 'Назначение сервиса', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-0-overview.md' },
{ text: 'ПО Veeam в аренду', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-1.md' },
{
text: 'Резервное копирование Veeam',
collapsed: true,
items: [
{ text: 'Резервное копирование Veeam - Обзор', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-0-overview.md' },
{
text: '1. Резервное копирование виртуальных машин (ВМ) с администрированием (Managed Cloud Backup)',
collapsed: true,
items: [
{ text: 'Managed Cloud Backup - Обзор', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-1/03-5-2-1-0-overview.md' },
{ text: '01. Описание сервиса', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-1/03-5-2-1-1.md' },
]
},
{
text: '2. Резервное копирование ВМ (Cloud Backup)',
collapsed: true,
items: [
{ text: 'Cloud Backup - Обзор', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-2/03-5-2-2-0-overview.md' },
{ text: '01. Описание сервиса', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-2/03-5-2-2-1.md' },
{ text: '02. Инструкция', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-2/03-5-2-2-2.md' },
]
},
{
text: '3. Резервное копирование в облако на базе Veeam Cloud Connect (Veeam Cloud Connect Backup)',
collapsed: true,
items: [
{ text: 'Veeam Cloud Connect Backup - Обзор', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-3/03-5-2-3-0-overview.md' },
{ text: '01. Состав сервиса', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-3/03-5-2-3-1.md' },
{ text: '02. Порядок подключения и зоны ответственности', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-3/03-5-2-3-2.md' },
{ text: '03. Тарификация и порядок оплаты', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-3/03-5-2-3-3.md' },
]
},
{
text: '4. Резервное копирование в облако на базе Veeam агента (Veeam Agent BackUp)',
collapsed: true,
items: [
{ text: 'Veeam Cloud Connect Backup - Обзор', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-4/03-5-2-4-0-overview.md' },
{ text: '01. Описание сервиса', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-4/03-5-2-4-1.md' },
{ text: '02. Инструкция',
collapsed: true,
items: [
{ text: '1. Описание портала', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-4/03-5-2-4-2/03-5-2-4-2-1.md' },
{ text: '2. Установка агента резервного копирования', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-4/03-5-2-4-2/03-5-2-4-2-2.md' },
{ text: '3. Настройка политики резервного копирования', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-4/03-5-2-4-2/03-5-2-4-2-3.md' },
{ text: '4. Восстановление из резервных копий', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-2/03-5-2-4/03-5-2-4-2/03-5-2-4-2-4.md' },
]
},
]
},
]
},
{
text: 'Резервное копирование Киберпротект',
collapsed: true,
items: [
{ text: 'О сервисе', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-3/03-5-3-0-overview.md' },
{
text: 'Инструкция по работе с сервисом',
collapsed: true,
items: [
{ text: '1. Начало работы с сервисом', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-3/03-5-3-1/03-5-3-1-1.md' },
{ text: '2. Резервное копирование агентами', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-3/03-5-3-1/03-5-3-1-2.md' },
{ text: '3. Установка и настройка агентов', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-3/03-5-3-1/03-5-3-1-3.md' },
{ text: '4. Представления консоли резервного копирования', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-3/03-5-3-1/03-5-3-1-4.md' },
{ text: '5. Резервное копирование приложений Microsoft', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-3/03-5-3-1/03-5-3-1-5.md' },
{ text: '6. Восстановление: памятка', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-3/03-5-3-1/03-5-3-1-6.md' },
{ text: '7. Другие способы восстановления', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-3/03-5-3-1/03-5-3-1-7.md' },
{ text: '8. Восстановление из ISO-образа', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-3/03-5-3-1/03-5-3-1-8.md' },
{ text: '9. Кроссплатформенная миграция на базе Киберпротект Облачный Бэкап', link: '/guide/wikidf/03-iaas/03-5-backup/03-5-3/03-5-3-1/03-5-3-1-9.md' },
]
},
]
},
]
},
]
},
]
},
],
'/terraform/': [
{
text: 'Terraform',
items: [
{
text: 'BeeCloud провайдер', link: '/terraform/providers/beecloud/index.md',
collapsed: true,
items: [
{
text: 'Облачные вычисления',
collapsed: true,
items: [
{
text: 'Источники данных',
items: [
{ text: 'beecloud_affinity_groups', link: '/terraform/providers/beecloud/compute/data-sources/beecloud_affinity_groups.md' },
{ text: 'beecloud_flavors', link: '/terraform/providers/beecloud/compute/data-sources/beecloud_flavors.md' },
{ text: 'beecloud_images', link: '/terraform/providers/beecloud/compute/data-sources/beecloud_images.md' },
{ text: 'beecloud_regions', link: '/terraform/providers/beecloud/compute/data-sources/beecloud_regions.md' },
{ text: 'beecloud_server', link: '/terraform/providers/beecloud/compute/data-sources/beecloud_server.md' },
{ text: 'beecloud_servers', link: '/terraform/providers/beecloud/compute/data-sources/beecloud_servers.md' },
{ text: 'beecloud_volume', link: '/terraform/providers/beecloud/compute/data-sources/beecloud_volume.md' },
{ text: 'beecloud_volumes', link: '/terraform/providers/beecloud/compute/data-sources/beecloud_volumes.md' },
],
},
{
text: 'Ресурсы',
items: [
{ text: 'beecloud_address_ip', link: '/terraform/providers/beecloud/compute/resources/beecloud_address_ip.md' },
{ text: 'beecloud_affinity_group', link: '/terraform/providers/beecloud/compute/resources/beecloud_affinity_group.md' },
{ text: 'beecloud_server', link: '/terraform/providers/beecloud/compute/resources/beecloud_server.md' },
{ text: 'beecloud_volume_bind', link: '/terraform/providers/beecloud/compute/resources/beecloud_volume_bind.md' },
{ text: 'beecloud_volume', link: '/terraform/providers/beecloud/compute/resources/beecloud_volume.md' },
]
},
]
},
{
text: 'DNS',
collapsed: true,
items: [
{
text: 'Источники данных',
items: [
{ text: 'beecloud_dns_records', link: '/terraform/providers/beecloud/dns/data-sources/beecloud_dns_records.md' },
{ text: 'beecloud_dns_zones', link: '/terraform/providers/beecloud/dns/data-sources/beecloud_dns_zones.md' },
],
},
{
text: 'Ресурсы',
items: [
{ text: 'beecloud_dns_record', link: '/terraform/providers/beecloud/dns/resources/beecloud_dns_record.md' },
]
},
]
},
]
},
{
text: 'Null провайдер', link: '/terraform/providers/null/index.md',
collapsed: true,
items: [
{
text: 'Источники данных',
collapsed: true,
items: [
{ text: 'null_resource', link: '/terraform/providers/null/resources/null_resource.md' },
],
},
{
text: 'Ресурсы',
collapsed: true,
items: [
{ text: 'null_data_source', link: '/terraform/providers/null/data-sources/null_data_source.md' },
]
},
]
},
{ text: 'Вопросы и ответы', link: '/terraform/faq.md' },
{text: 'Обзор', link: '/platform/about.md'},
{text: 'Техническая поддержка', link: '/platform/support/support-overview.md'},
],
},
],
'/start/': [
{
text: 'Начало работы в Beeline Cloud', link: '/start/index.md',
},
{text: 'Начать работу', link: '/start/getting-started.md'},
{text: 'Бесплатный период', link: '/start/trial.md'},
{text: 'Платное использование', link: '/start/organization.md'},
],
'/ai/': [
{ text: 'AI платформа', link: '/ai/index.md' },
{ text: 'Обзор сервиса', link: '/ai/ai-overview-platform.md' },
{ text: 'Быстрый старт', link: '/ai/ai-getting-started.md' },
{ text: 'Управление сервисом', link: '/ai/ai-setting.md' },
{ text: 'Чат с LLM', link: '/ai/ai-chat-llm.md' },
{ text: 'Концепции', link: '/ai/ai-glossary.md' },
],
'/vdc/': [
{
text: 'Виртуальные дата-центры на VMware', link: '/vdc/index.md',
},
{
text: 'Обзор сервиса', link: '/vdc/vdc-overview.md',
collapsed: true,
items: [
{ text: 'Техническое описание', link: '/vdc/vdc-tech.md' },
{ text: 'Квоты и лимиты', link: '/vdc/vdc-quatos.md' },
]
},
{
text: 'Быстрый старт', link: '/vdc/vdc-getting-started.md'
},
{ text: 'Виртуальные дата-центры', link: '/vdc/vdc-how-to/vdc-index.md',
collapsed: true,
items: [
{ text: 'Создание дата-центра', link: '/vdc/vdc-how-to/vdc-create.md' },
{ text: 'Вход в дата-центр', link: '/vdc/vdc-how-to/vdc-enter.md' },
{ text: 'Управление дата-центром', link: '/vdc/vdc-how-to/vdc-manage.md'},
],
},
{ text: 'Виртуальные машины', link: '/vdc/vdc-how-to/vm/vm-index.md',
collapsed: true,
items: [
{text: 'Создание ВМ', link: '/vdc/vdc-how-to/vm/create-vm.md'},
{text: 'Создание vApp', link: '/vdc/vdc-how-to/vm/create-vapp.md'},
{text: 'Клонирование ВМ', link: '/vdc/vdc-how-to/vm/clone-vm.md'},
{text: 'Изменение конфигурации ВМ', link: '/vdc/vdc-how-to/vm/edit-vm.md'},
{text: 'Удаление ВМ', link: '/vdc/vdc-how-to/vm/delete-vm.md'},
{text: 'Группы размещения', link: '/vdc/vdc-how-to/vm/create-affinity-rules.md'},
{ text: 'Снимки ВМ', link: '/vdc/vdc-how-to/vm/create-snapshot.md'},
],
},
{ text: 'Сети', link: '/vdc/vdc-how-to/networks/networks-index.md',
collapsed: true,
items: [
{text: 'Настройка доступа к ВМ из интернета', link: '/vdc/vdc-how-to/networks/allow-external-connections-to-vm.md'},
{text: 'Подключение ВМ в vApp к сети', link: '/vdc/vdc-how-to/networks/connect-vapp-to-network.md'},
{text: 'Подключение ВМ к интернету', link: '/vdc/vdc-how-to/networks/connect-vm-to-network.md'},
{text: 'Создание сети в организации и подключение к Edge Gateway', link: '/vdc/vdc-how-to/networks/create-network.md'},
{text: 'Подключение сети к Edge Gateway', link: '/vdc/vdc-how-to/networks/isolated-to-routed.md'},
],
},
{ text: 'Пользователи и роли', link: '/vdc/vdc-how-to/users/users-index.md',
collapsed: true,
items: [
{text: 'Ролевая модель', link: '/vdc/vdc-how-to/users/roles.md'},
{text: 'Создание пользователя', link: '/vdc/vdc-how-to/users/add-user.md'},
{text: 'Изменение пароля пользователя', link: '/vdc/vdc-how-to/users/change-users-password.md'},
{text: 'Настройка квот', link: '/vdc/vdc-how-to/users/quotas.md'},
],
},
{ text: 'Двухфакторная аутентификация', link: '/vdc/vdc-how-to/vdc-2fa.md',
collapsed: true,
items: [
{text: 'Подключение 2FA', link: '/vdc/vdc-how-to/vdc-2fa-start.md'},
{text: 'Управление 2FA', link: '/vdc/vdc-how-to/vdc-2fa-manage.md'},
],
},
],
// { text: 'Тарификация', link: '/vdc/vdc-tarif.md' },
'/compute/': [
{
text: 'Виртуальные машины', link: '/compute/index.md',
},
{ text: 'Обзор сервиса', link: '/compute/compute-overview.md' },
{text: 'Быстрый старт', link: '/compute/compute-getting-started.md'},
{ text: 'Виртуальные машины', link: '/compute/compute-how-to/compute-index.md',
collapsed: true,
items: [
{ text: 'Создание ВМ', link: '/compute/compute-how-to/compute-servers-create.md' },
{ text: 'Подключение к ВМ', link: '/compute/compute-how-to/compute-connect-index.md',
collapsed: true,
items: [
{ text: 'Подключение по SSH к ВМ по внешнему IP-адресу', link: '/compute/compute-how-to/compute-connect-public.md'},
{ text: 'Подключение по SSH к ВМ по внутреннему IP-адресу', link: '/compute/compute-how-to/compute-connect-inside.md' },
]
},
{ text: 'Управление ВМ', link: '/compute/compute-how-to/compute-servers-manage.md' },
],
},
{ text: 'Диски', link: '/compute/compute-how-to/compute-disks.md' },
{ text: 'IP-адреса', link: '/compute/compute-how-to/compute-ip.md' },
{ text: 'Группы размещения', link: '/compute/compute-how-to/compute-affinity.md' },
{ text: 'Сети', link: '/compute/compute-how-to/compute-network/compute-network-index.md',
collapsed: true,
items: [
{ text: 'Настройка site-to-site VPN с помощью VyOS', link: '/compute/compute-how-to/compute-network/compute-vpn-vyos.md' },
{ text: 'Подключение ВМ закрытого контура к интернету', link: '/compute/compute-how-to/compute-network/compute-network-inside.md' },
],
},
],
'/admin/': [
{
text: 'Администрирование', link: '/admin/index.md',
},
{text: 'Управление ключевыми парами', link: '/admin/ssh.md'},
],
'/billing/': [
{ text: 'Биллинг', link: '/billing/about.md',
collapsed: true,
items: [
{ text: 'Аналитика потребления', link: '/billing/usage-analytics.md' },
],
},
],
'/concepts/': [
{text: 'Виртуальные дата-центры', link: '/concepts/datacenters.md'},
{text: 'DNS', link: '/concepts/dns.md'},
{text: 'Edge Gateway', link: '/concepts/edge-gateway.md'},
{text: 'NAT', link: '/concepts/nat.md'},
{text: 'Типы сетей в vDC', link: '/concepts/network-types.md'},
{text: 'Ролевая модель', link: '/concepts/roles.md'},
{text: 'vApp', link: '/concepts/vApp.md'},
],
'/monitoring/': [
{
text: 'Мониторинг', link: '/monitoring/about.md',
},
],
},
},
}
})
)
+1 -1
View File
@@ -106,7 +106,7 @@ export default function(parameters: IParameters) {
// window._paq elsewhere when needed, including closure scopes.
const _paq = window._paq;
// If user requests consent checking, do this before we actually track.
// Note: this doesn't work at the moment because the user has no way to set
// tip: this doesn't work at the moment because the user has no way to set
// whether consent was given. Oops.
if (requireConsent) {
_paq.push(['requireConsent']);
+13 -1
View File
@@ -26,6 +26,12 @@ export const overrideComponents = () => (
new URL('./theme/components/CustomContent.vue', import.meta.url)
)
},
{
find: /^.*\/VPHome\.vue$/,
replacement: fileURLToPath(
new URL('./theme/components/CustomHome.vue', import.meta.url)
)
},
{
find: /^.*\/VPDocFooter\.vue$/,
replacement: fileURLToPath(
@@ -41,7 +47,7 @@ export const overrideComponents = () => (
{
find: /^.*\/VPFeature\.vue$/,
replacement: fileURLToPath(
new URL('./theme/components/CustomFeature.vue', import.meta.url)
new URL('./theme/components/CustomHomeFeature.vue', import.meta.url)
)
},
{
@@ -62,6 +68,12 @@ export const overrideComponents = () => (
new URL('./theme/components/CustomNavBarSearchButton.vue', import.meta.url)
)
},
{
find: /^.*\/VPHomeHero\.vue$/,
replacement: fileURLToPath(
new URL('./theme/components/CustomHomeHero.vue', import.meta.url)
)
},
{
find: /^.*\/VPLocalSearchBox\.vue$/,
replacement: fileURLToPath(
@@ -0,0 +1,46 @@
<template>
<div :class="[$style.CustomFeatureImage, classes]">
<CustomIcon :icon="icon" size="large" />
</div>
</template>
<script setup lang="ts">
import { Icons } from '@beeline/design-tokens/js/iconfont/icons';
import { computed, useCssModule } from 'vue';
import CustomIcon from './CustomIcon.vue';
const { size = 'medium' } = defineProps<{
icon: Icons,
size?: 'medium' | 'small'
}>()
const style = useCssModule()
const classes = computed(() => ({
[style.CustomAvatar]: true,
[style.CustomAvatarSmall]: size === 'small'
}))
</script>
<style lang="scss" module>
@use '@beeline/design-tokens/scss/tokens/components/avatar';
@use "@beeline/design-tokens/scss/tokens/themes";
.CustomAvatar {
border-radius: avatar.$avatar-squircle-border-radius;
display: flex;
justify-content: center;
align-items: center;
height: avatar.$avatar-medium-height;
width: avatar.$avatar-medium-width;
letter-spacing: avatar.$avatar-medium-text-font-letter-spacing;
line-height: avatar.$avatar-medium-text-font-line-height;
font-size: avatar.$avatar-medium-text-font-size;
background-color: themes.$color-status-neutral-background;
&Small {
height: avatar.$avatar-small-height;
width: avatar.$avatar-small-width;
}
}
</style>
@@ -5,7 +5,7 @@ import { EXTERNAL_URL_RE } from 'vitepress/dist/client/shared'
interface Props {
tag?: string
size?: 'medium' | 'big'
size?: 'medium' | 'big' | 'small'
theme?: 'brand' | 'alt' | 'sponsor'
text: string
href?: string
@@ -51,6 +51,15 @@ const component = computed(() => {
transition: color 0.1s, border-color 0.1s, background-color 0.1s;
}
.VPButton.small {
border-radius: 12px;
padding: 0 16px;
line-height: 20px;
height: 40px;
font-size: 15px;
font-weight: 500;
}
.VPButton.medium {
border-radius: 12px;
padding: 0 20px;
@@ -11,49 +11,82 @@ const { hasSidebar } = useSidebar()
</script>
<template>
<div
class="VPContent CustomContent"
id="VPContent"
:class="{
<div class="VPContent CustomContent" id="VPContent" :class="{
'has-sidebar': hasSidebar,
'is-home': frontmatter.layout === 'home'
}"
>
<slot name="not-found" v-if="page.isNotFound"><NotFound /></slot>
}">
<slot name="not-found" v-if="page.isNotFound">
<NotFound />
</slot>
<VPPage v-else-if="frontmatter.layout === 'page'">
<template #page-top><slot name="page-top" /></template>
<template #page-bottom><slot name="page-bottom" /></template>
<template #page-top>
<slot name="page-top" />
</template>
<template #page-bottom>
<slot name="page-bottom" />
</template>
</VPPage>
<VPHome v-else-if="frontmatter.layout === 'home'">
<template #home-hero-before><slot name="home-hero-before" /></template>
<template #home-hero-info><slot name="home-hero-info" /></template>
<template #home-hero-image><slot name="home-hero-image" /></template>
<template #home-hero-after><slot name="home-hero-after" /></template>
<template #home-features-before><slot name="home-features-before" /></template>
<template #home-features-after><slot name="home-features-after" /></template>
<template #home-hero-before>
<slot name="home-hero-before" />
</template>
<template #home-hero-info>
<slot name="home-hero-info" />
</template>
<template #home-hero-image>
<slot name="home-hero-image" />
</template>
<template #home-hero-after>
<slot name="home-hero-after" />
</template>
<template #home-features-before>
<slot name="home-features-before" />
</template>
<template #home-features-after>
<slot name="home-features-after" />
</template>
</VPHome>
<component
v-else-if="frontmatter.layout && frontmatter.layout !== 'doc'"
:is="frontmatter.layout"
/>
<component v-else-if="frontmatter.layout && frontmatter.layout !== 'doc'" :is="frontmatter.layout" />
<CustomDoc v-else>
<template #doc-top><slot name="doc-top" /></template>
<template #doc-bottom><slot name="doc-bottom" /></template>
<template #doc-top>
<slot name="doc-top" />
</template>
<template #doc-bottom>
<slot name="doc-bottom" />
</template>
<template #doc-footer-before><slot name="doc-footer-before" /></template>
<template #doc-before><slot name="doc-before" /></template>
<template #doc-after><slot name="doc-after" /></template>
<template #doc-footer-before>
<slot name="doc-footer-before" />
</template>
<template #doc-before>
<slot name="doc-before" />
</template>
<template #doc-after>
<slot name="doc-after" />
</template>
<template #aside-top><slot name="aside-top" /></template>
<template #aside-outline-before><slot name="aside-outline-before" /></template>
<template #aside-outline-after><slot name="aside-outline-after" /></template>
<template #aside-ads-before><slot name="aside-ads-before" /></template>
<template #aside-ads-after><slot name="aside-ads-after" /></template>
<template #aside-bottom><slot name="aside-bottom" /></template>
<template #aside-top>
<slot name="aside-top" />
</template>
<template #aside-outline-before>
<slot name="aside-outline-before" />
</template>
<template #aside-outline-after>
<slot name="aside-outline-after" />
</template>
<template #aside-ads-before>
<slot name="aside-ads-before" />
</template>
<template #aside-ads-after>
<slot name="aside-ads-after" />
</template>
<template #aside-bottom>
<slot name="aside-bottom" />
</template>
</CustomDoc>
</div>
</template>
@@ -82,7 +115,7 @@ const { hasSidebar } = useSidebar()
.VPContent.has-sidebar {
margin: var(--vp-layout-top-height, 0px) 0 0;
padding-left: var(--vp-sidebar-width);
padding-left: 320px;
}
}
+62 -53
View File
@@ -5,11 +5,13 @@ import { useData } from 'vitepress/dist/client/theme-default/composables/data'
import { useSidebar } from 'vitepress/dist/client/theme-default/composables/sidebar'
import VPDocAside from 'vitepress/dist/client/theme-default/components/VPDocAside.vue'
import VPDocFooter from 'vitepress/dist/client/theme-default/components/VPDocFooter.vue'
import SectionLinkList from './SectionLinkList/SectionLinkList.vue'
const { theme } = useData()
const route = useRoute()
const { hasSidebar, hasAside, leftAside } = useSidebar()
const { frontmatter } = useData()
const pageName = computed(() =>
route.path.replace(/[./]+/g, '_').replace(/_html$/, '')
@@ -17,10 +19,7 @@ const pageName = computed(() =>
</script>
<template>
<div
class="VPDoc CustomDoc"
:class="{ 'has-sidebar': hasSidebar, 'has-aside': hasAside }"
>
<div class="VPDoc CustomDoc" :class="{ 'has-sidebar': hasSidebar, 'has-aside': hasAside }">
<slot name="doc-top" />
<div class="container">
<div v-if="hasAside" class="aside" :class="{'left-aside': leftAside}">
@@ -28,12 +27,24 @@ const pageName = computed(() =>
<div class="aside-container">
<div class="aside-content">
<VPDocAside>
<template #aside-top><slot name="aside-top" /></template>
<template #aside-bottom><slot name="aside-bottom" /></template>
<template #aside-outline-before><slot name="aside-outline-before" /></template>
<template #aside-outline-after><slot name="aside-outline-after" /></template>
<template #aside-ads-before><slot name="aside-ads-before" /></template>
<template #aside-ads-after><slot name="aside-ads-after" /></template>
<template #aside-top>
<slot name="aside-top" />
</template>
<template #aside-bottom>
<slot name="aside-bottom" />
</template>
<template #aside-outline-before>
<slot name="aside-outline-before" />
</template>
<template #aside-outline-after>
<slot name="aside-outline-after" />
</template>
<template #aside-ads-before>
<slot name="aside-ads-before" />
</template>
<template #aside-ads-after>
<slot name="aside-ads-after" />
</template>
</VPDocAside>
</div>
</div>
@@ -43,16 +54,16 @@ const pageName = computed(() =>
<div class="content-container">
<slot name="doc-before" />
<main class="main">
<Content
class="vp-doc"
:class="[
<Content class="vp-doc" :class="[
pageName,
theme.externalLinkIcon && 'external-link-icon-enabled'
]"
/>
]" />
<SectionLinkList v-if="frontmatter.section_links" :links="frontmatter.section_links" />
</main>
<VPDocFooter>
<template #doc-footer-before><slot name="doc-footer-before" /></template>
<template #doc-footer-before>
<slot name="doc-footer-before" />
</template>
</VPDocFooter>
<slot name="doc-after" />
</div>
@@ -62,58 +73,70 @@ const pageName = computed(() =>
</div>
</template>
<style scoped>
<style scoped lang="scss">
@use 'src/assets/scss/app/helpers/media';
.VPDoc {
padding: 32px 24px 96px;
width: 100%;
}
@media (min-width: 768px) {
.VPDoc {
@include media.media_min(960px) {
padding: 48px 32px 0;
}
@include media.media_max(768px) {
padding: 48px 32px 128px;
}
}
@media (min-width: 960px) {
.VPDoc {
padding: 48px 32px 0;
.VPDoc:not(.has-sidebar) .container {
@include media.media_min(1440px) {
max-width: 1104px;
}
.VPDoc:not(.has-sidebar) .container {
display: flex;
@include media.media_max(960px) {
padding: 0 32px 128px;display: flex;
justify-content: center;
max-width: 992px;
}
}
.VPDoc:not(.has-sidebar) .content {
.VPDoc:not(.has-sidebar) .content {
@include media.media_min(1440px) {
max-width: 784px;
}
@include media.media_max(960px) {
max-width: 752px;
}
}
@media (min-width: 1280px) {
.VPDoc .container {
.VPDoc .container {
@include media.media_min(1280px) {
display: flex;
justify-content: center;
}
.VPDoc .aside {
display: block;
}
}
@media (min-width: 1440px) {
.VPDoc:not(.has-sidebar) .content {
max-width: 784px;
}
.VPDoc:not(.has-sidebar) .container {
max-width: 1104px;
.VPDoc .aside {
@include media.media_min(1280px) {
display: block;
}
}
.container {
margin: 0 auto;
width: 100%;
@include media.media_min(1280px) {
order: 1;
margin: 0;
min-width: 640px;
}
@include media.media_max(960px) {
padding: 0 32px 128px;
}
}
.aside {
@@ -169,20 +192,6 @@ const pageName = computed(() =>
width: 100%;
}
@media (min-width: 960px) {
.content {
padding: 0 32px 128px;
}
}
@media (min-width: 1280px) {
.content {
order: 1;
margin: 0;
min-width: 640px;
}
}
.content-container {
margin: 0 auto;
}
@@ -1,129 +0,0 @@
<script setup lang="ts">
import type { DefaultTheme } from 'vitepress/theme'
import VPImage from 'vitepress/dist/client/theme-default/components/VPImage.vue'
import VPLink from 'vitepress/dist/client/theme-default/components/VPLink.vue'
import VPIconArrowRight from 'vitepress/dist/client/theme-default/components/icons/VPIconArrowRight.vue'
defineProps<{
icon?: DefaultTheme.FeatureIcon
title: string
details?: string
link?: string
linkText?: string
rel?: string
target?: string
}>()
</script>
<template>
<VPLink
class="VPFeature CustomFeature"
:href="link"
:rel="rel"
:target="target"
:no-icon="true"
:tag="link ? 'a' : 'div'"
>
<article class="box">
<div v-if="typeof icon === 'object' && icon.wrap" class="icon">
<VPImage
:image="icon"
:alt="icon.alt"
:height="icon.height || 48"
:width="icon.width || 48"
/>
</div>
<VPImage
v-else-if="typeof icon === 'object'"
:image="icon"
:alt="icon.alt"
:height="icon.height || 48"
:width="icon.width || 48"
/>
<div v-else-if="icon" class="icon" v-html="icon"></div>
<h2 class="title" v-html="title"></h2>
<p v-if="details" class="details" v-html="details"></p>
<div v-if="linkText" class="link-text">
<p class="link-text-value">
{{ linkText }} <VPIconArrowRight class="link-text-icon" />
</p>
</div>
</article>
</VPLink>
</template>
<style scoped>
.VPFeature {
display: block;
border: 1px solid var(--vp-c-bg-soft);
border-radius: 12px;
height: 100%;
background-color: var(--vp-c-bg-soft);
transition: border-color 0.25s, background-color 0.25s;
}
.VPFeature.link:hover {
border-color: var(--vp-c-brand-1);
}
.box {
display: flex;
flex-direction: column;
padding: 24px;
height: 100%;
}
.box > :deep(.VPImage) {
margin-bottom: 20px;
}
.icon {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
border-radius: 6px;
background-color: var(--vp-c-default-soft);
width: 48px;
height: 48px;
font-size: 24px;
transition: background-color 0.25s;
}
.title {
line-height: 24px;
font-size: 18px;
font-weight: 500;
color: var(--color-text-active);
}
.details {
flex-grow: 1;
padding-top: 8px;
line-height: 24px;
font-size: 15px;
font-weight: 500;
color: var(--color-text-inactive);
}
.link-text {
padding-top: 8px;
}
.link-text-value {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 500;
color: var(--vp-c-brand-1);
}
.link-text-icon {
display: inline-block;
margin-left: 6px;
width: 14px;
height: 14px;
fill: currentColor;
}
</style>
+51 -63
View File
@@ -1,8 +1,10 @@
<script setup lang="ts">
import { type Ref, inject } from 'vue'
import { type Ref, inject, ref } from 'vue'
import type { DefaultTheme } from 'vitepress/theme'
import CustomButton from './CustomButton.vue'
import VPImage from 'vitepress/dist/client/theme-default/components/VPImage.vue'
import HomeHeroSearchButton from './HomeHeroSearchButton.vue'
import VPLocalSearchBox from 'vitepress/dist/client/theme-default/components/VPLocalSearchBox.vue'
export interface HeroAction {
theme?: 'brand' | 'alt'
@@ -14,11 +16,14 @@ defineProps<{
name?: string
text?: string
tagline?: string
search?: boolean
image?: DefaultTheme.ThemeableImage
actions?: HeroAction[]
}>()
const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
const showSearch = ref(false)
</script>
<template>
@@ -27,21 +32,20 @@ const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
<div class="main">
<slot name="home-hero-info">
<h1 v-if="name" class="name">
<span v-html="name" class="clip"></span>
{{ name }}
</h1>
<p v-if="text" v-html="text" class="text"></p>
<p v-if="tagline" v-html="tagline" class="tagline"></p>
</slot>
<div v-if="search" class="VPHeroSearchWrapper">
<VPLocalSearchBox v-if="showSearch" @close="showSearch = false" />
<HomeHeroSearchButton @click="showSearch = true" />
</div>
<div v-if="actions" class="actions">
<div v-for="action in actions" :key="action.link" class="action">
<CustomButton
tag="a"
size="medium"
:theme="action.theme"
:text="action.text"
:href="action.link"
/>
<CustomButton tag="a" size="medium" :theme="action.theme" :text="action.text" :href="action.link" />
</div>
</div>
</div>
@@ -59,20 +63,26 @@ const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
</template>
<style lang="scss" scoped>
@use "@beeline/design-tokens/scss/tokens/themes";
@use "@beeline/design-tokens/scss/tokens/globals/sizes";
@use "@beeline/design-tokens/scss/mixin";
$topSpacing: 40px;
.VPHero {
margin-top: calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);
padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px;
padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + $topSpacing) 24px 48px;
}
@media (min-width: 640px) {
.VPHero {
padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px;
padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + $topSpacing) 48px 64px;
}
}
@media (min-width: 960px) {
.VPHero {
padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px;
padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + $topSpacing) 64px 64px;
}
}
@@ -80,7 +90,7 @@ const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
display: flex;
flex-direction: column;
margin: 0 auto;
max-width: 1152px;
max-width: 1080px;
}
@media (min-width: 960px) {
@@ -95,46 +105,41 @@ const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
order: 2;
flex-grow: 1;
flex-shrink: 0;
}
.VPHero.has-image .container {
text-align: center;
}
@media (min-width: 960px) {
background-color: themes.$color-background-secondary;
padding: 98px 92px;
border-radius: sizes.$size-border-radius-x6;
.VPHero.has-image .container {
text-align: left;
text-align: center;
}
}
@media (min-width: 960px) {
.main {
order: 1;
width: calc((100% / 3) * 2);
}
@media (min-width: 960px) {
.main {
order: 1;
width: calc((100% / 3) * 2);
.VPHero.has-image .main {
max-width: 592px;
}
}
.VPHero.has-image .main {
max-width: 592px;
.name,
.text {
@include mixin.h1;
white-space: pre-wrap;
}
}
.name,
.text {
max-width: 392px;
letter-spacing: -0.4px;
line-height: 40px;
font-size: 32px;
font-weight: 700;
white-space: pre-wrap;
}
.VPHero.has-image .name,
.VPHero.has-image .text {
margin: 0 auto;
}
.name {
color: var(--vp-home-hero-name-color);
.VPHero.has-image .name,
.VPHero.has-image .text {
margin: 0 auto;
}
.name {
color: themes.$color-text-active;
padding-bottom: 40px;
text-align: center;
}
}
.clip {
@@ -144,22 +149,7 @@ const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
-webkit-text-fill-color: var(--vp-home-hero-name-color);
}
@media (min-width: 640px) {
.name,
.text {
max-width: 576px;
line-height: 56px;
font-size: 48px;
}
}
@media (min-width: 960px) {
.name,
.text {
line-height: 64px;
font-size: 56px;
}
.VPHero.has-image .name,
.VPHero.has-image .text {
margin: 0;
@@ -168,7 +158,6 @@ const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
.tagline {
padding-top: 8px;
max-width: 392px;
line-height: 28px;
font-size: 18px;
font-weight: 500;
@@ -183,7 +172,6 @@ const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
@media (min-width: 640px) {
.tagline {
padding-top: 12px;
max-width: 576px;
line-height: 32px;
font-size: 20px;
}
@@ -0,0 +1,39 @@
<script setup lang="ts">
import VPHomeHero from 'vitepress/dist/client/theme-default/components/VPHomeHero.vue'
import CustomHomeFeatures from './CustomHomeFeatures.vue';
import CustomHomeServices from './CustomHomeServices.vue';
</script>
<template>
<div class="VPHome CustomHome">
<slot name="home-hero-before" />
<VPHomeHero>
<template #home-hero-info>
<slot name="home-hero-info" />
</template>
<template #home-hero-image>
<slot name="home-hero-image" />
</template>
</VPHomeHero>
<slot name="home-hero-after" />
<slot name="home-features-before" />
<CustomHomeFeatures />
<slot name="home-features-after" />
<CustomHomeServices />
<Content />
</div>
</template>
<style scoped>
.VPHome {
padding-bottom: 96px;
}
.VPHome :deep(.VPHomeSponsors) {
margin-top: 112px;
margin-bottom: -128px;
}
</style>
@@ -0,0 +1,129 @@
<script setup lang="ts">
import VPLink from 'vitepress/dist/client/theme-default/components/VPLink.vue'
import { computed, useCssModule } from 'vue';
import { NAVBAR_HEIGHT } from '../constants'
import { Icons } from '@beeline/design-tokens/js/iconfont/icons'
import CustomAvatar from './CustomAvatar.vue';
const { disabled, scrollTo, link, items } = defineProps<{
icon: string
title: string
link?: string
scrollTo?: string
disabled?: boolean
items?: ItemFeature[]
}>()
type ItemFeature = {
title: string
link?: string
}
const style = useCssModule()
const classes = computed(() => ({
[style.CustomFeature]: true,
[style.CustomFeatureDisabled]: disabled || !link && !scrollTo,
}))
const handleClick = (event: Event) => {
if (scrollTo) {
const targetElTop = document.querySelector(scrollTo)?.getBoundingClientRect().top
if (targetElTop) {
event.stopPropagation()
window.scrollTo({ behavior: 'smooth', top: targetElTop + window.scrollY - NAVBAR_HEIGHT - 32 })
}
}
}
</script>
<template>
<Component :is="!disabled && link ? VPLink : 'article'"
:class="classes" @click="handleClick">
<CustomAvatar :class="$style.CustomFeatureIcon" :icon="icon as Icons" />
<div :class="$style.CustomFeatureContent">
<Component :is="!disabled && link ? VPLink : 'article'" v-bind="{ ...(!disabled && link && { href: link }) }">
<p :class="$style.CustomFeatureTitle" :href="`/docs${link}`">
{{ title }}
</p>
</Component>
<div :class="$style.CustomFeatureContainer">
<div v-for="(item, i) in items" :key="i">
<Component
:is="!disabled && item.link ? VPLink : 'article'"
v-bind="{ ...(!disabled && item.link && { href: item.link }) }"
:class="{ [style.CustomFeatureDisabled]: disabled || !item.link }"
>
<p :class="$style.CustomFeatureSubtitle">{{ item.title }}</p>
</Component>
</div>
</div>
</div>
</Component>
</template>
<style lang="scss" module>
@use "@beeline/design-tokens/scss/tokens/globals/sizes";
@use "@beeline/design-tokens/scss/tokens/themes";
@use "@beeline/design-tokens/scss/mixin";
.CustomFeature {
$el: &;
border-radius: sizes.$size-border-radius-x6;
border: 1px solid themes.$color-border;
max-width: 344px;
padding: sizes.$size-spacing-x8 sizes.$size-spacing-x6;
&WithScroll {
cursor: pointer;
}
&Icon {
#{$el}Disabled & {
color: themes.$color-text-disabled;
}
}
&Content {
display: flex;
flex-direction: column;
padding-top: sizes.$size-spacing-x4;
gap: sizes.$size-spacing-x6;
}
&Title {
@include mixin.h4;
color: themes.$color-text-active;
&:hover {
color: themes.$color-text-link;
}
#{$el}Disabled & {
color: themes.$color-text-disabled;
}
}
&Subtitle {
@include mixin.caption;
&:hover {
color: themes.$color-text-link;
}
#{$el}Disabled & {
color: themes.$color-text-disabled;
}
#{$el}WithScroll & {
color: themes.$color-text-active;
}
}
&Container {
display: flex;
gap: sizes.$size-spacing-x4;
}
}
</style>
@@ -0,0 +1,26 @@
<script setup lang="ts">
import { useData } from 'vitepress'
import CustomHomeFeature from './CustomHomeFeature.vue'
const { frontmatter } = useData()
</script>
<template>
<div v-if="Array.isArray(frontmatter.features)" :class="$style.HomeFeatures">
<CustomHomeFeature v-for="feature in frontmatter.features" :key="feature.title" :title="feature.title"
:icon="feature.icon" :link="feature.link" :scrollTo="feature.scroll_to" :disabled="feature.disabled" :items="feature.items" />
</div>
</template>
<style lang="scss" module>
@use "@beeline/design-tokens/scss/tokens/globals/sizes";
.HomeFeatures {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: sizes.$size-spacing-x8 sizes.$size-spacing-x6;
max-width: 1080px;
margin: 0 auto;
margin-bottom: 80px;
}
</style>
@@ -0,0 +1,18 @@
<script setup lang="ts">
import { useData } from 'vitepress/dist/client/theme-default/composables/data'
import VPHero from 'vitepress/dist/client/theme-default/components/VPHero.vue'
const { frontmatter: fm } = useData()
</script>
<template>
<VPHero v-if="fm.hero" class="CustomHomeHero" :name="fm.hero.name" :text="fm.hero.text" :tagline="fm.hero.tagline"
:search="fm.hero.search" :image="fm.hero.image" :actions="fm.hero.actions">
<template #home-hero-info>
<slot name="home-hero-info" />
</template>
<template #home-hero-image>
<slot name="home-hero-image" />
</template>
</VPHero>
</template>
@@ -0,0 +1,109 @@
<template>
<div :class="$style.CustomHomeServiceCard">
<h3 :class="$style.CustomHomeServiceCardTitle">{{ title }}</h3>
<div :class="$style.CustomHomeServiceCardLinks">
<Component v-for="article in articles" :is="!article.disabled && article.link ? VPLink : 'div'"
v-bind="{ ...(!article.disabled && article.link && { href: article.link }) }"
:class="[$style.CustomHomeServiceCardLink, { [$style.CustomHomeServiceCardLinkDisabled]: article.disabled || !article.link }]">
<div :class="$style.CustomHomeServiceCardLinkTitle">
<div :class="[$style.CustomHomeServiceCardLinkTitleIcon, { [$style.CustomHomeServiceCardLinkTitleIconActive] : article.link && article.icon === 'magic' }]">
<CustomIcon :icon="(article.icon || 'cloud') as Icons" />
</div>
<div :class="[$style.CustomHomeServiceCardLinkTitleText, { [$style.CustomHomeServiceCardLinkTitleTextActive]: article.link }]">
{{ article.title }}
</div>
</div>
<div :class="$style.CustomHomeServiceCardLinkDescription">
{{ article.description }}
</div>
</Component>
</div>
</div>
</template>
<script setup lang="ts">
import VPLink from 'vitepress/dist/client/theme-default/components/VPLink.vue'
import CustomIcon from './CustomIcon.vue'
import { Icons } from '@beeline/design-tokens/js/iconfont/icons'
export type ServiceArticle = {
title: string
description: string
icon: string
link?: string
disabled?: boolean
}
defineProps<{
title: string
articles: ServiceArticle[]
}>()
</script>
<style lang="scss" module>
@use "@beeline/design-tokens/scss/tokens/globals/sizes";
@use "@beeline/design-tokens/scss/tokens/themes";
@use "@beeline/design-tokens/scss/mixin";
.CustomHomeServiceCard {
background-color: themes.$color-background-secondary;
border-radius: sizes.$size-border-radius-x6;
padding: sizes.$size-spacing-x8 sizes.$size-spacing-x6;
&Title {
@include mixin.h4();
color: themes.$color-text-active;
margin-bottom: sizes.$size-spacing-x6;
}
&Links {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: sizes.$size-spacing-x6;
}
&Link {
$iconRightSpacing: 8px;
$iconSize: 20px;
$el: &;
color: themes.$color-text-active !important;
&Disabled {
color: themes.$color-text-disabled !important;
}
&Title {
margin-bottom: sizes.$size-spacing-x1;
display: flex;
align-items: center;
&Icon {
width: $iconSize;
height: $iconSize;
margin-right: $iconRightSpacing;
&Active {
color: themes.$color-text-link;
}
}
&Text {
@include mixin.subtitle2;
&Active:hover {
color: themes.$color-text-link;
}
}
}
&Description {
padding-left: calc($iconSize + $iconRightSpacing);
color: themes.$color-text-inactive;
@include mixin.caption;
}
}
}
</style>
@@ -0,0 +1,41 @@
<template>
<div :class="$style.CustomHomeServices">
<h2 id="home-services-section-title" :class="$style.CustomHomeServicesTitle">Документация по сервисам</h2>
<div v-if="Array.isArray(frontmatter.services)" :class="$style.CustomHomeServicesList">
<CustomHomeServiceCard v-for="service in frontmatter.services" :key="service.title" :title="service.title"
:articles="service.articles" />
</div>
</div>
</template>
<script setup lang="ts">
import { useData } from 'vitepress';
import CustomHomeServiceCard from './CustomHomeServiceCard.vue';
const { frontmatter } = useData()
</script>
<style lang="scss" module>
@use "@beeline/design-tokens/scss/tokens/globals/sizes";
@use "@beeline/design-tokens/scss/tokens/themes";
@use "@beeline/design-tokens/scss/mixin";
.CustomHomeServices {
max-width: 1080px;
margin: 0 auto;
&Title {
@include mixin.h2;
text-align: center;
margin-bottom: 40px;
color: themes.$color-text-active;
}
&List {
display: flex;
flex-direction: column;
gap: sizes.$size-spacing-x6;
}
}
</style>
@@ -0,0 +1,36 @@
<template>
<i :class="['beeline-icons', `beeline-icons-${icon}`, classes]"></i>
</template>
<script setup lang="ts">
import { Icons } from '@beeline/design-tokens/js/iconfont/icons';
import { computed, useCssModule } from 'vue';
const { size = 'medium' } = defineProps<{
icon: Icons,
size?: 'large' | 'medium' | 'small'
}>()
const style = useCssModule()
const classes = computed(() => ({
[style.CustomIcon]: true,
[style.CustomIconLarge]: size === 'large',
[style.CustomIconSmall]: size === 'small'
}))
</script>
<style lang="scss" module>
@use "@beeline/design-tokens/scss/tokens/components/icon";
.CustomIcon {
font-size: icon.$icon-medium-size !important;
&Large {
font-size: icon.$icon-large-size !important;
}
&Small {
font-size: icon.$icon-small-size !important;
}
}
</style>
@@ -10,7 +10,7 @@ import {
useSessionStorage
} from '@vueuse/core'
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
import Mark from 'mark.js/src/vanilla.js'
import Mark from 'mark.js/dist/mark'
import MiniSearch, { type SearchResult } from 'minisearch'
import { dataSymbol, inBrowser, useRouter } from 'vitepress'
import {
@@ -20,6 +20,7 @@ import {
nextTick,
onBeforeUnmount,
onMounted,
Raw,
ref,
shallowRef,
watch,
@@ -132,6 +133,7 @@ watchEffect(() => {
const results: Ref<(SearchResult & Result)[]> = shallowRef([])
const enableNoResults = ref(false)
const loadig = ref(true)
watch(filterText, () => {
enableNoResults.value = false
@@ -160,11 +162,7 @@ debouncedWatch(
if (!index) return
// Search
results.value = index
.search(filterTextValue)
.slice(0, 16) as (SearchResult & Result)[]
enableNoResults.value = true
retrySearch(index, filterTextValue)
// Highlighting
const mods = showDetailedListValue
? await Promise.all(results.value.map((r) => fetchExcerpt(r.id)))
@@ -268,6 +266,16 @@ function focusSearchInput(select = true) {
select && searchInput.value?.select()
}
const retrySearch = (index: Raw<MiniSearch<Result>>, filter: string) => {
if (!index) return
results.value = index
.search(filter)
.slice(0, 16) as (SearchResult & Result)[]
enableNoResults.value = true
}
onMounted(() => {
focusSearchInput()
})
@@ -481,33 +489,6 @@ function formMarkRegex(terms: Set<string>) {
class="search-input"
/>
<div class="search-actions">
<button
v-if="!disableDetailedView"
class="toggle-layout-button"
type="button"
:class="{ 'detailed-list': showDetailedList }"
:title="$t('modal.displayDetails')"
@click="
selectedIndex > -1 && (showDetailedList = !showDetailedList)
"
>
<svg
width="18"
height="18"
viewBox="0 0 24 24"
aria-hidden="true"
>
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M3 14h7v7H3zM3 3h7v7H3zm11 1h7m-7 5h7m-7 6h7m-7 5h7"
/>
</svg>
</button>
<button
class="clear-button"
type="reset"
@@ -535,6 +516,7 @@ function formMarkRegex(terms: Set<string>) {
</form>
<ul
v-if="!!results.length"
ref="resultsEl"
:id="results?.length ? 'localsearch-list' : undefined"
:role="results?.length ? 'listbox' : undefined"
@@ -561,29 +543,21 @@ function formMarkRegex(terms: Set<string>) {
>
<div>
<div class="titles">
<span class="title-icon">#</span>
<span
v-for="(t, index) in p.titles"
:key="index"
class="title"
>
<span class="text" v-html="t" />
<svg width="18" height="18" viewBox="0 0 24 24">
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m9 18l6-6l-6-6"
/>
</svg>
<span class="text"> > </span>
</span>
<span class="title main">
<span class="text" v-html="p.title" />
</span>
</div>
<span v-html="p.title" />
<div v-if="showDetailedList" class="excerpt-wrapper">
<div v-if="p.text" class="excerpt" inert>
<div class="vp-doc" v-html="p.text" />
@@ -594,65 +568,21 @@ function formMarkRegex(terms: Set<string>) {
</div>
</a>
</li>
<li
v-if="filterText && !results.length && enableNoResults"
class="no-results"
>
{{ $t('modal.noResultsText') }} "<strong>{{ filterText }}</strong
>"
</li>
</ul>
<div class="search-keyboard-shortcuts">
<span>
<kbd :aria-label="$t('modal.footer.navigateUpKeyAriaLabel')">
<svg width="14" height="14" viewBox="0 0 24 24">
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 19V5m-7 7l7-7l7 7"
/>
</svg>
</kbd>
<kbd :aria-label="$t('modal.footer.navigateDownKeyAriaLabel')">
<svg width="14" height="14" viewBox="0 0 24 24">
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 5v14m7-7l-7 7l-7-7"
/>
</svg>
</kbd>
{{ $t('modal.footer.navigateText') }}
</span>
<span>
<kbd :aria-label="$t('modal.footer.selectKeyAriaLabel')">
<svg width="14" height="14" viewBox="0 0 24 24">
<g
fill="none"
stroke="currentcolor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
>
<path d="m9 10l-5 5l5 5" />
<path d="M20 4v7a4 4 0 0 1-4 4H4" />
</g>
</svg>
</kbd>
{{ $t('modal.footer.selectText') }}
</span>
<span>
<kbd :aria-label="$t('modal.footer.closeKeyAriaLabel')">esc</kbd>
{{ $t('modal.footer.closeText') }}
</span>
</div>
<ul
v-else-if="filterText && !results.length && enableNoResults"
class="no-results"
>
<p class="no-results-text">
{{ $t('modal.noResultsText') }}
</p>
<button
class="no-results-button"
@click="retrySearch(searchIndex, filterText)"
>
Попробовать еще раз
</button>
</ul>
</div>
</div>
</Teleport>
@@ -675,16 +605,13 @@ function formMarkRegex(terms: Set<string>) {
.shell {
position: relative;
padding: 12px;
padding: 24px;
margin: 64px auto;
display: flex;
flex-direction: column;
gap: 16px;
background: var(--vp-local-search-bg);
width: min(100vw - 60px, 900px);
height: min-content;
max-height: min(100vh - 128px, 900px);
border-radius: 6px;
border-radius: 12px;
}
@media (max-width: 767px) {
@@ -698,7 +625,7 @@ function formMarkRegex(terms: Set<string>) {
}
.search-bar {
border: 1px solid var(--vp-c-divider);
border: 1px solid rgb(32, 33, 35);
border-radius: 12px;
display: flex;
align-items: center;
@@ -712,10 +639,6 @@ function formMarkRegex(terms: Set<string>) {
}
}
.search-bar:focus-within {
border-color: var(--vp-c-brand-1);
}
.search-icon {
margin: 8px;
}
@@ -802,27 +725,31 @@ function formMarkRegex(terms: Set<string>) {
}
.results {
display: flex;
flex-direction: column;
gap: 6px;
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
box-shadow: var(--vp-c-shadow-3);
border-radius: 12px;
border: 1px solid rgba(25, 28, 52, 0.18);
padding: 8px 0;
max-height: min(100vh - 214px, 900px);
li:hover {
background-color: rgba(25, 28, 52, 0.08);
}
}
.result {
display: flex;
align-items: center;
gap: 8px;
border-radius: 12px;
transition: none;
line-height: 1rem;
border: solid 2px var(--vp-local-search-result-border);
outline: none;
height: 66px;
}
.result > div {
margin: 12px;
margin: 12px 16px;
width: 100%;
overflow: hidden;
}
@@ -840,6 +767,13 @@ function formMarkRegex(terms: Set<string>) {
position: relative;
z-index: 1001;
padding: 2px 0;
font-size: 13px !important;
line-height: 16px !important;
}
:deep(mark) {
background-color: transparent;
color: none;
}
.title {
@@ -852,21 +786,10 @@ function formMarkRegex(terms: Set<string>) {
font-weight: 500;
}
.title-icon {
opacity: 0.5;
font-weight: 500;
color: var(--vp-c-brand-1);
}
.title svg {
opacity: 0.5;
}
.result.selected {
--vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);
border-color: var(--vp-local-search-result-selected-border);
}
.excerpt-wrapper {
position: relative;
}
@@ -892,10 +815,7 @@ function formMarkRegex(terms: Set<string>) {
.titles :deep(mark),
.excerpt :deep(mark) {
background-color: var(--vp-local-search-highlight-bg);
color: var(--vp-local-search-highlight-text);
border-radius: 2px;
padding: 0 2px;
background-color: transparent;
}
.excerpt :deep(.vp-code-group) .tabs {
@@ -932,12 +852,42 @@ function formMarkRegex(terms: Set<string>) {
}
.no-results {
font-size: 0.9rem;
text-align: center;
padding: 12px;
padding: 28px 0;
display: flex;
flex-direction: column;
gap: 24px;
align-items: center;
z-index: 100;
box-shadow: 0 0 10 0 rgba(0, 0, 0, 0.16);
border-radius: 12px;
border: 1px solid rgba(25, 28, 52, 0.18);
background-color: rgb(255, 255, 255);
}
.no-results-text {
font-weight: 700;
font-size: 17px;
line-height: 22px;
letter-spacing: 0.2px;
}
.no-results-button {
border-radius: 12px;
border: 1px solid rgba(25, 28, 52, 0.18);
padding: 13px 20px;
font-weight: 500;
font-size: 17px;
line-height: 22px;
letter-spacing: 0.2px;
}
svg {
flex: none;
}
.text {
font-size: 13px !important;
line-height: 16px !important;
color: rgba(25, 28, 52, 0.48);
}
</style>
@@ -12,6 +12,7 @@ import VPNavBarSearch from 'vitepress/dist/client/theme-default/components/VPNav
import VPNavBarSocialLinks from 'vitepress/dist/client/theme-default/components/VPNavBarSocialLinks.vue'
import CustomNavBarTitle from './CustomNavBarTitle.vue'
import VPNavBarTranslations from 'vitepress/dist/client/theme-default/components/VPNavBarTranslations.vue'
import CustomButton from './CustomButton.vue'
defineProps<{
isScreenOpen: boolean
@@ -27,6 +28,7 @@ const { hasLocalNav } = useLocalNav()
const { frontmatter } = useData()
const classes = ref<Record<string, boolean>>({})
const loginUrl = import.meta.env.VITE_LOGIN_URL
watchPostEffect(() => {
classes.value = {
@@ -43,22 +45,21 @@ watchPostEffect(() => {
<div class="container">
<div class="title">
<CustomNavBarTitle>
<template #nav-bar-title-before><slot name="nav-bar-title-before" /></template>
<template #nav-bar-title-after><slot name="nav-bar-title-after" /></template>
<template #nav-bar-title-before>
<slot name="nav-bar-title-before" />
</template>
<template #nav-bar-title-after>
<slot name="nav-bar-title-after" />
</template>
</CustomNavBarTitle>
</div>
<div class="content">
<div class="content-body">
<slot name="nav-bar-content-before" />
<VPNavBarSearch class="search" />
<VPNavBarMenu class="menu" />
<VPNavBarTranslations class="translations" />
<VPNavBarAppearance class="appearance" />
<VPNavBarSocialLinks class="social-links" />
<VPNavBarExtra class="extra" />
<slot name="nav-bar-content-after" />
<VPNavBarHamburger class="hamburger" :active="isScreenOpen" @click="$emit('toggle-screen')" />
<VPNavBarSearch class="search" />
<!-- <CustomButton text="Войти" size="small" :href="loginUrl" /> -->
</div>
</div>
</div>
@@ -105,7 +106,7 @@ watchPostEffect(() => {
@media (min-width: 768px) {
.wrapper {
padding: 0 32px;
padding: 0 24px;
}
}
@@ -174,7 +175,7 @@ watchPostEffect(() => {
position: relative;
z-index: 1;
padding-right: 32px;
padding-left: var(--vp-sidebar-width);
padding-left: 0px;
}
}
@@ -187,7 +188,7 @@ watchPostEffect(() => {
.content-body {
display: flex;
justify-content: flex-end;
justify-content: space-between;
align-items: center;
height: var(--vp-nav-height);
transition: background-color 0.5s;
@@ -221,6 +222,10 @@ watchPostEffect(() => {
height: 24px;
background-color: var(--vp-c-divider);
content: "";
font-weight: 500;
font-size: 15px;
line-height: 20px;
letter-spacing: 0.2px;
}
.menu + .appearance::before,
@@ -251,4 +256,9 @@ watchPostEffect(() => {
background-color: rgba(255, 255, 255, 0.2);
}
}
.search {
justify-content: flex-end;
margin-right: 24px;
}
</style>
@@ -3,12 +3,16 @@ import type { DefaultTheme } from 'vitepress/theme'
import { useData } from 'vitepress/dist/client/theme-default/composables/data'
import { isActive } from 'vitepress/dist/client/shared'
import VPLink from 'vitepress/dist/client/theme-default/components/VPLink.vue'
import { computed, ref } from 'vue'
defineProps<{
item: DefaultTheme.NavItemWithLink
}>()
const { page } = useData()
const textRef = ref<HTMLElement | null>(null)
const wrapperWidth = computed(() => textRef.value?.offsetWidth)
</script>
<template>
@@ -20,22 +24,32 @@ const { page } = useData()
page.relativePath,
item.activeMatch || item.link,
!!item.activeMatch
)
),
disabled: !isActive(
page.relativePath,
item.activeMatch || item.link,
!!item.activeMatch
) && !item.link ? 'disabled' : '',
}"
:href="item.link"
:target="item.target"
:rel="item.rel"
tabindex="0"
>
<span v-html="item.text"></span>
<span
ref="textRef"
v-html="item.text"
/>
</VPLink>
</template>
<style scoped>
<style lang="scss" scoped>
@use '@beeline/design-tokens/scss/tokens/globals/colors';
.VPNavBarMenuLink {
display: flex;
align-items: center;
padding: 0 12px;
padding: 0 24px;
line-height: var(--vp-nav-height);
font-size: 16px;
font-weight: 500;
@@ -45,9 +59,32 @@ const { page } = useData()
.VPNavBarMenuLink.active {
color: var(--color-text-active);
&::after {
position: absolute;
bottom: 0;
content: '';
height: 4px;
display: none;
width: calc(v-bind(wrapperWidth) * 1px);
border-top-left-radius: 12px;
border-top-right-radius: 12px;
background-color: colors.$color-background-brand;
}
&.active {
&::after {
display: block;
}
}
}
.VPNavBarMenuLink:hover {
.disabled {
opacity: 0.45;
pointer-events: none;
}
.VPNavBarMenuLink:hover:not(.disabled) {
color: var(--color-text-active);
}
</style>
@@ -14,31 +14,22 @@ const $t = createSearchTranslate(defaultTranslations)
</script>
<template>
<button type="button" class="DocSearch DocSearch-Button CustomDocSearch-Button" :aria-label="$t('button.buttonAriaLabel')">
<span class="DocSearch-Button-Container">
<svg
class="DocSearch-Search-Icon"
width="20"
height="20"
viewBox="0 0 20 20"
aria-label="search icon"
>
<path
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
stroke="currentColor"
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<span class="DocSearch-Button-Placeholder">{{ $t('button.buttonText') }}</span>
</span>
<span class="DocSearch-Button-Keys">
<kbd class="DocSearch-Button-Key"></kbd>
<kbd class="DocSearch-Button-Key">K</kbd>
</span>
</button>
<svg
class="DocSearch-Search-Icon"
width="20"
height="20"
viewBox="0 0 20 20"
aria-label="search icon"
>
<path
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
stroke="currentColor"
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</template>
<style>
@@ -65,156 +56,13 @@ const $t = createSearchTranslate(defaultTranslations)
--docsearch-hit-shadow: none;
}
.DocSearch-Button {
display: flex;
justify-content: center;
align-items: center;
border-radius: 12px;
margin: 0;
padding: 0;
width: 48px;
height: 55px;
background: transparent;
transition: border-color 0.25s;
}
.DocSearch-Button:hover {
background: transparent;
}
.DocSearch-Button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
.DocSearch-Button:focus:not(:focus-visible) {
outline: none !important;
}
@media (min-width: 768px) {
.DocSearch-Button {
justify-content: flex-start;
border: 1px solid transparent;
border-radius: 12px;
padding: 0 10px 0 12px;
width: 100%;
height: 40px;
background-color: var(--vp-c-bg-alt);
}
.DocSearch-Button:hover {
border-color: var(--vp-c-brand-1);
background: var(--vp-c-bg-alt);
}
}
.DocSearch-Button .DocSearch-Button-Container {
display: flex;
align-items: center;
}
.DocSearch-Button .DocSearch-Search-Icon {
.DocSearch-Search-Icon {
position: relative;
width: 16px;
height: 16px;
width: 18px;
height: 18px;
color: var(--vp-c-text-1);
fill: currentColor;
transition: color 0.5s;
}
.DocSearch-Button:hover .DocSearch-Search-Icon {
color: var(--vp-c-text-1);
}
@media (min-width: 768px) {
.DocSearch-Button .DocSearch-Search-Icon {
top: 1px;
margin-right: 8px;
width: 14px;
height: 14px;
color: var(--vp-c-text-2);
}
}
.DocSearch-Button .DocSearch-Button-Placeholder {
display: none;
margin-top: 2px;
padding: 0 16px 0 0;
font-size: 13px;
font-weight: 500;
color: var(--vp-c-text-2);
transition: color 0.5s;
}
.DocSearch-Button:hover .DocSearch-Button-Placeholder {
color: var(--vp-c-text-1);
}
@media (min-width: 768px) {
.DocSearch-Button .DocSearch-Button-Placeholder {
display: inline-block;
}
}
.DocSearch-Button .DocSearch-Button-Keys {
/*rtl:ignore*/
direction: ltr;
display: none;
min-width: auto;
}
@media (min-width: 768px) {
.DocSearch-Button .DocSearch-Button-Keys {
display: flex;
align-items: center;
}
}
.DocSearch-Button .DocSearch-Button-Key {
display: block;
margin: 2px 0 0 0;
border: 1px solid var(--vp-c-divider);
/*rtl:begin:ignore*/
border-right: none;
border-radius: 4px 0 0 4px;
padding-left: 6px;
/*rtl:end:ignore*/
min-width: 0;
width: auto;
height: 22px;
line-height: 22px;
font-family: var(--vp-font-family-base);
font-size: 12px;
font-weight: 500;
transition: color 0.5s, border-color 0.5s;
}
.DocSearch-Button .DocSearch-Button-Key + .DocSearch-Button-Key {
/*rtl:begin:ignore*/
border-right: 1px solid var(--vp-c-divider);
border-left: none;
border-radius: 0 4px 4px 0;
padding-left: 2px;
padding-right: 6px;
/*rtl:end:ignore*/
}
.DocSearch-Button .DocSearch-Button-Key:first-child {
font-size: 0 !important;
}
.DocSearch-Button .DocSearch-Button-Key:first-child:after {
content: 'Ctrl';
font-size: 12px;
letter-spacing: normal;
color: var(--docsearch-muted-color);
}
.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after {
content: '\2318';
}
.DocSearch-Button .DocSearch-Button-Key:first-child > * {
display: none;
margin: 8px;
}
</style>
@@ -38,10 +38,10 @@ const target = computed(() =>
:target="target"
>
<slot name="nav-bar-title-before" />
<VPImage v-if="theme.logo" class="logo" :image="theme.logo" />
<template v-if="theme.siteTitle">{{ theme.siteTitle }}</template>
<template v-else-if="theme.siteTitle === undefined">{{ site.title }}</template>
<slot name="nav-bar-title-after" />
<VPImage v-if="theme.logo" class="logo" :image="theme.logo" />
</a>
</div>
</template>
@@ -53,10 +53,13 @@ const target = computed(() =>
border-bottom: 1px solid transparent;
width: 100%;
height: var(--vp-nav-height);
font-size: 16px;
font-weight: 600;
color: var(--vp-c-text-1);
font-size: 25px;
font-weight: 500;
line-height: 28px;
color: var(--color-text-inactive);
transition: opacity 0.25s;
gap: 20px;
margin-right: 24px;
}
@media (min-width: 960px) {
@@ -72,7 +75,6 @@ const target = computed(() =>
}
:deep(.logo) {
margin-right: 8px;
height: var(--vp-nav-logo-height);
}
</style>
@@ -60,9 +60,8 @@ watch(
bottom: 0;
left: 0;
z-index: var(--vp-z-index-sidebar);
padding: 32px 32px 96px 32px;
width: 256px;
max-width: 320px;
padding: 0px 0px 96px 0px;
width: 320px;
background-color: var(--vp-sidebar-bg-color);
opacity: 0;
box-shadow: var(--vp-c-shadow-3);
@@ -88,8 +87,6 @@ watch(
@media (min-width: 960px) {
.VPSidebar {
padding-top: var(--vp-nav-height);
// width: var(--vp-sidebar-width);
// max-width: 100%;
background-color: var(--vp-sidebar-bg-color);
opacity: 1;
visibility: visible;
@@ -98,13 +95,6 @@ watch(
}
}
@media (min-width: 1440px) {
.VPSidebar {
// padding-left: max(32px, calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));
// width: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px);
}
}
@media (min-width: 960px) {
.curtain {
position: sticky;
@@ -121,17 +111,14 @@ watch(
.nav {
outline: 0;
}
.group + .group {
border-top: 1px solid var(--vp-c-divider);
padding-top: 10px;
padding-top: 24px;
width: 100%;
}
@media (min-width: 960px) {
.group {
padding-top: 10px;
width: calc(var(--vp-sidebar-width) - 64px);
width: 100%;
}
}
</style>
@@ -0,0 +1,53 @@
<script lang="ts" setup>
import type { ButtonTranslations } from 'vitepress/types/local-search'
import { createSearchTranslate } from 'vitepress/dist/client/theme-default/support/translation'
const defaultTranslations: { button: ButtonTranslations } = {
button: {
buttonText: 'Поиск',
buttonAriaLabel: 'Поиск'
}
}
const $t = createSearchTranslate(defaultTranslations)
</script>
<template>
<button type="button" :class="$style.HomeHeroSearchButton" :aria-label="$t('button.buttonAriaLabel')">
<span :class="$style.HomeHeroSearchButtonContainer">
<img :class="$style.HomeHeroSearchButtonIcon" src="/icons/search.svg" alt="Поиск">
<span :class="$style.HomeHeroSearchButtonPlaceholder">{{ $t('button.buttonText') }}</span>
</span>
</button>
</template>
<style lang="scss" module>
@use "@beeline/design-tokens/scss/tokens/themes";
@use "@beeline/design-tokens/scss/tokens/globals/sizes";
@use "@beeline/design-tokens/scss/mixin";
@use "@beeline/design-tokens/scss/tokens/components/search";
.HomeHeroSearchButton {
display: flex;
width: 100%;
align-items: center;
border-radius: search.$search-border-radius;
height: search.$search-medium-height;
background: search.$search-background-color;
&Container {
display: flex;
}
&Icon {
margin: 0 search.$search-category-icon-spacing;
color: themes.$color-text-inactive;
fill: currentColor;
}
&Placeholder {
@include mixin.body2;
color: themes.$color-text-disabled;
}
}
</style>
@@ -0,0 +1,9 @@
export type SectionLinkListItem = {
title: string,
link: string,
description?: string
}
export type SectionLinkListProps = {
links: SectionLinkListItem[]
}
@@ -0,0 +1,58 @@
<template>
<div :class="$style.SectionLinkList">
<div v-for="link in links" :key="link.title" :class="$style.SectionLinkListItem">
<div :class="$style.SectionLinkListLink">
<VPLink :href="link.link">{{ link.title }}</VPLink>
</div>
<div :class="$style.SectionLinkListDescription">
{{ link.description }}
</div>
</div>
</div>
</template>
<script setup lang="ts">
import VPLink from 'vitepress/dist/client/theme-default/components/VPLink.vue';
import { SectionLinkListProps } from './SectionLinkList.types'
defineProps<SectionLinkListProps>()
</script>
<style lang="scss" module>
@use "@beeline/design-tokens/scss/tokens/themes";
@use "@beeline/design-tokens/scss/tokens/globals/sizes";
@use "@beeline/design-tokens/scss/mixin";
.SectionLinkList {
$el: &;
display: grid;
grid-template-columns: 1fr 1fr;
gap: sizes.$size-spacing-x6 sizes.$size-spacing-x6;
margin-top: sizes.$size-spacing-x10;
&Item {
display: flex;
flex-direction: column;
gap: sizes.$size-spacing-x2;
// max-width: 315px;
}
&Link {
a,
a:hover,
a:visited,
a:active {
color: themes.$color-text-link;
text-decoration: none;
@include mixin.subtitle3;
}
}
&Description {
color: themes.$color-text-inactive;
@include mixin.body3;
}
}
</style>
+1
View File
@@ -0,0 +1 @@
export const NAVBAR_HEIGHT = 64
@@ -0,0 +1,27 @@
@use "@beeline/design-tokens/scss/tokens/themes";
@use "@beeline/design-tokens/scss/tokens/globals/sizes";
.SectionLinkList {
$el: &;
display: grid;
grid-template-columns: 1fr 1fr;
gap: sizes.$size-spacing-x6 sizes.$size-spacing-x6;
margin-top: sizes.$size-spacing-x10;
&__Item {
display: flex;
flex-direction: column;
gap: sizes.$size-spacing-x2;
max-width: 315px;
}
&__Link {
a {
text-decoration: none;
}
}
&__Description {
color: themes.$color-text-inactive;
}
}
@@ -1,4 +1,5 @@
@use "vp-doc.scss";
@use "vp-custom-block.scss";
@use "vp-doc-aside.scss";
@use "vp-sidebar.scss";
@use "vp-doc";
@use "vp-custom-block";
@use "vp-doc-aside";
@use "vp-sidebar";
@use "SectionLinkList";
@@ -1,10 +1,52 @@
.VPDocAside {
.outline-link {
font-size: 16px;
}
@use '@beeline/design-tokens/scss/tokens/components/navigationDrawer';
@use "@beeline/design-tokens/scss/tokens/globals/colors";
.outline-title {
font-size: 17px;
font-weight: 500;
.VPDocAside {
.outline-link {
font-weight: 400;
font-size: 17px;
line-height: 22px;
letter-spacing: 0.2px;
padding-top: 8px;
padding-bottom: 8px;
white-space: unset;
color: colors.$color-text-grey-inactive;
}
.outline-link.active {
font-weight: 500 !important;
color: colors.$color-text-black-active;
}
.outline-title {
font-size: 17px;
font-weight: 500;
line-height: 22px;
padding-bottom: 16px;
}
.content {
padding-left: 0px !important;
border-left: 0px !important;
nav {
border-left: 1px solid var(--vp-c-divider) !important;
.outline-link {
padding-left: 20px !important;
&.active {
padding-left: 16px !important;
position: relative !important;
left: -1px !important;
border-left: navigationDrawer.$navigation-drawer-item-indicator-width solid
navigationDrawer.$navigation-drawer-item-activated-indicator-color !important;
border-top-right-radius: navigationDrawer.$navigation-drawer-item-indicator-border-radius-topright !important;
border-bottom-right-radius: navigationDrawer.$navigation-drawer-item-indicator-border-radius-bottomright !important;
}
}
}
}
}
@@ -1,3 +1,6 @@
@use "@beeline/design-tokens/scss/tokens/globals/colors";
@use "@beeline/design-tokens/scss/tokens/themes";
@mixin font_style($fontSize, $fontWeight, $lineHeight, $letterSpacing) {
font-size: $fontSize;
font-weight: $fontWeight;
@@ -66,7 +69,7 @@
}
li + li {
margin-top: 50px;
margin-top: 34px;
}
ul li {
@@ -75,16 +78,6 @@
margin-top: 8px;
}
ol li:nth-last-of-type(n+2)::after {
content: '';
border-left: 1px solid rgb(201, 197, 197);
position: absolute;
line-height: 100%;
left: -30px;
top: 43px;
bottom: -30px;
}
ol li::before {
content: counter(list);
counter-increment: list;
@@ -94,8 +87,8 @@
left: -48px;
width: 35px;
height: 35px;
background-color: #7e00ed;
color: #fff;
background-color: colors.$color-background-brand;
color: themes.$color-text-active;
text-align: center;
line-height: 25px;
font-size: 16px;
@@ -115,6 +108,10 @@
padding: 0;
}
ol li:last-child, ul li:last-child {
margin-bottom: 40px;
}
ol li p {
margin-top: 0;
}
@@ -1,7 +1,116 @@
@use '@beeline/design-tokens/scss/tokens/components/navigationDrawer';
@use '@beeline/design-tokens/scss/tokens/themes/theme-variables' as theme;
@use 'src/assets/scss/app/helpers/media';
.VPSidebar {
&Item {
.text {
font-size: 15px;
}
--vp-sidebar-bg-color: var(--vp-c-bg);
}
.VPSidebar .VPSidebarItem .item {
margin: 4px 0;
}
.VPSidebar .VPSidebarItem .link {
display: flex;
align-items: center;
}
.indicator {
border-top-right-radius: navigationDrawer.$navigation-drawer-item-indicator-border-radius-topright !important;
border-bottom-right-radius: navigationDrawer.$navigation-drawer-item-indicator-border-radius-bottomright !important;
position: absolute !important;
left: 0 !important;
}
.VPSidebarItem.is-active > .item .link > .text {
color: theme.$color-text-active !important;
font-weight: 500 !important;
line-height: 20px !important;
}
.VPSidebarItem {
.item {
padding: 12px 32px !important;
border-top-right-radius: 12px !important;
border-bottom-right-radius: 12px !important;
color: theme.$color-text-inactive;
&:hover {
background-color: navigationDrawer.$navigation-drawer-item-hover-background-color !important;
color: theme.$color-text-inactive;
}
}
&.is-active > .item > .indicator {
border-left: navigationDrawer.$navigation-drawer-item-indicator-width solid
navigationDrawer.$navigation-drawer-item-activated-indicator-color !important;
}
}
.VPSidebarItem.collapsible {
.items {
margin-left: 16px;
.item {
padding: 12px 16px 12px 56px !important;
border-top-left-radius: 12px !important;
border-bottom-left-radius: 12px !important;
}
}
&.is-active,
&.has-active {
> .item {
.indicator {
display: block !important;
border-left: navigationDrawer.$navigation-drawer-item-indicator-width solid
navigationDrawer.$navigation-drawer-item-activated-indicator-color !important;
}
.text {
color: theme.$color-text-active !important;
font-weight: 500 !important;
}
}
}
.items .VPSidebarItem.is-active > .item {
background-color: navigationDrawer.$navigation-drawer-item-hover-background-color !important;
.text {
color: theme.$color-text-active !important;
font-weight: 500 !important;
}
}
}
.VPSidebarItem.collapsible .items .item .indicator {
display: none !important;
}
.text {
padding: 0px !important;
font-weight: 400 !important;
font-size: 15px !important;
line-height: 18px !important;
letter-spacing: 0.2px !important;
transition-property: all;
transition-duration: 150ms;
transition-timing-function: ease-in-out;
color: theme.$color-text-inactive !important;
}
.VPSidebarItem .items {
border-left: 0px !important;
}
.VPSidebarItem {
padding-bottom: 0px !important;
}
.VPLocalNav.has-sidebar {
@include media.max(sm) {
padding-left: 0px;
}
}
@@ -1,3 +1,6 @@
@use '@beeline/design-tokens/scss/tokens/themes/dark';
@use '@beeline/design-tokens/scss/tokens/themes';
:root {
--color-text-active: rgba(9, 11, 22, 0.94);
--color-text-inactive: rgba(25, 28, 52, 0.7);
@@ -7,9 +10,13 @@
--color-button-contained-background-color: #fdd835;
--color-button-contained-hover-background-color: #fdc435;
--color-button-contained-text-color: rgba(9, 11, 22, 0.94);
@include themes.theme();
}
.dark {
--color-text-active: rgba(255, 255, 255, 0.87);
--color-text-inactive: rgba(255, 255, 255, 0.6);
@include themes.theme(dark.$theme);
}
+5
View File
@@ -1,3 +1,8 @@
@use "@beeline/design-tokens/scss/iconfont/iconfont" with (
$font-path-iconfont: '/fonts/iconfont'
);
@use "@beeline/design-tokens/scss/iconfont/icons";
$font-path-beeline-sans: '/fonts/beeline-sans' !default;
@mixin beeline-sans-font($type, $weight, $style: normal) {
+3 -3
View File
@@ -1,4 +1,4 @@
@use "fonts.scss";
@use "design-system.scss";
@use "vars.scss";
@use "fonts";
@use "design-system";
@use "vars";
@use "components";
+3
View File
@@ -203,3 +203,6 @@
--docsearch-primary-color: var(--vp-c-brand-1) !important;
}
:root {
--vp-sidebar-width: 320px;
}
+14
View File
@@ -0,0 +1,14 @@
---
section_links:
- title: Управление ключевыми парами
link: /admin/ssh.md
description: Добавление SSH-ключей для подключения к виртуальным машинам
---
# Администрирование
При [регистрации пользователя](../start/getting-started.md#1-регистрация-в-beeline-cloud) в Beeline Cloud создается аккаунт и проект в Beeline Cloud.
С помощью аккаунта можно управлять профилем пользователя - добавлять SSH-ключи, чтобы подключаться к виртуальным машинам без ввода пароля.
В проекте можно создавать ресурсы, добавлять пользователей в проект и управлять доступом к ресурсам.
@@ -10,7 +10,7 @@
| Название квоты | Количество |
|---------------------|------------|
| Количество виртуальных серверов | 3 штуки|
| Количество виртуальных ВМов | 3 штуки|
| ЦПУ | 200 |
| ОЗУ | 200 Гбайт |
| Хранилище NVME | 5000 Гбайт |
@@ -11,7 +11,7 @@
- сетевые диски;
- IP-адреса.
Аппаратные ресурсы (серверы, сети, диски) размещены в центрах обработки данных (ЦОД). Каждый дата-центр разделен на модули. Модули оснащены независимыми системами электропитания и охлаждения.
Аппаратные ресурсы (ВМы, сети, диски) размещены в центрах обработки данных (ЦОД). Каждый дата-центр разделен на модули. Модули оснащены независимыми системами электропитания и охлаждения.
При получении доступа в публичное облако текущий пользователь становится менеджера проектов. Менеджер проектов может создавать новые проекты, в которых он получает роль владельца проекта. Владелец проекта может добавлять пользователей в проект, назначая им роли.
+16 -16
View File
@@ -7,28 +7,28 @@
В проекте предусмотрен базовый набор ролей:
- **Владелец продукта** — управление пользователями проекта, просмотр ресурсов.
- **DevOps-инженер** — управление инфраструктурой, стандартное администрирование ОС UNIX по протоколу ssh и права управления виртуальными серверами и дисками в консоли управления.
- **DevOps-инженер** — управление инфраструктурой, стандартное администрирование ОС UNIX по протоколу ssh и права управления виртуальными ВМами и дисками в консоли управления.
## Матрица ролей
| Действие | Владелец проекта | DevOps-инженер |
|---|---|---|
| Обзор проекта<br> (квоты и количество использованных ресурсов)| &#9989; | &#9989; |
| Серверы: обзор | &#9989; | &#9989; |
| Серверы: мониторинг | &#9989; | &#9989; |
| Серверы: создать сервер |&#10008; | &#9989; |
| Серверы: подключить диск | &#10008; | &#9989; |
| Серверы: отключить диск | &#10008; | &#9989; |
| Серверы: добавить диск | &#10008; | &#9989; |
| Серверы: теги | &#10008; |&#9989; |
| Серверы: масштабирование сервера | &#10008; | &#9989; |
| Серверы: выключить сервер | &#10008; | &#9989; |
| Серверы: включить сервер | &#10008; | &#9989; |
| Серверы: перезагрузить сервер | &#10008; | &#9989; |
| Серверы: принудительно перезагрузить сервер | &#10008; | &#9989; |
| Серверы: удалить сервер | &#10008; | &#9989; |
| Серверы: группы размещения | &#10008; | &#9989; |
| Серверы: IP-адреса | &#10008; | &#9989; |
| ВМы: обзор | &#9989; | &#9989; |
| ВМы: мониторинг | &#9989; | &#9989; |
| ВМы: создать ВМ |&#10008; | &#9989; |
| ВМы: подключить диск | &#10008; | &#9989; |
| ВМы: отключить диск | &#10008; | &#9989; |
| ВМы: добавить диск | &#10008; | &#9989; |
| ВМы: теги | &#10008; |&#9989; |
| ВМы: масштабирование ВМа | &#10008; | &#9989; |
| ВМы: выключить ВМ | &#10008; | &#9989; |
| ВМы: включить ВМ | &#10008; | &#9989; |
| ВМы: перезагрузить ВМ | &#10008; | &#9989; |
| ВМы: принудительно перезагрузить ВМ | &#10008; | &#9989; |
| ВМы: удалить ВМ | &#10008; | &#9989; |
| ВМы: группы размещения | &#10008; | &#9989; |
| ВМы: IP-адреса | &#10008; | &#9989; |
| Диски: просмотр дисков | &#9989; | &#9989; |
| Диски: добавление дискового пространства | &#10008; | &#9989; |
| Диски: удалить диск| &#10008; | &#9989; |
+56
View File
@@ -0,0 +1,56 @@
# Управление ключевыми парами
SSH-ключи используются для подключения к виртуальной машине по SSH. SSH-ключ позволит подключаться к виртуальному серверу без ввода пароля.
SSH-ключ состоит из публичного и приватного ключей: публичный ключ хранится в профиле пользователя в публичном облаке, приватный — хранится у пользователя.
::: warning Важно
SSH-ключ добавляется на этапе [создания виртуальной машины](../compute/compute-how-to/compute-servers-create.md#создать-виртуальную-машину). Подключиться к существующим виртуальным машинам по SSH-ключу не получится.
:::
## Добавить SSH-ключ
1. Войдите в [личный кабинет](https://lk.cloud.beeline.ru/).
2. Перейдите в профиль пользователя в правом верхнем углу.
3. Перейдите в раздел **SSH-ключи**.
4. Нажмите **Добавить ключ**.
5. Укажите название ключа.
6. Откройте терминал и сгенерируйте ключевую пару. Можно использовать команду:
```sh
ssh-keygen -t ed25519 -C “login” -Z aes256-gcm@openssh.com
```
7. Результатом выполнения команды будет сгенерированная ключевая пара. По умолчанию ключи сохраняются в каталоге `~/.ssh` для ОС Linux или `C:\users\имя_пользователя\.ssh\` для ОС Windows.
8. Перейдите в каталог с ключевой парой и скопируйте публичную часть ключа. Пример публичной части ключа:
```
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5ABFLIFyapYheN7OZNhTaNqEHefjmU5mtzK********+gRPCz user@Desktop
```
9. Перейдите в консоль управления и вставьте скопированную публичную часть ключа в поле **SSH-ключ**.
10. Нажмите **Сохранить**.
## Посмотреть SSH-ключи
1. Войдите в [личный кабинет](https://lk.cloud.beeline.ru/).
2. Перейдите в профиль пользователя в правом верхнем углу.
3. Перейдите в раздел **SSH-ключи**.
4. В таблице показаны SSH-ключи пользователя.
## Изменить название SSH-ключа
1. Войдите в [личный кабинет](https://lk.cloud.beeline.ru/).
2. Перейдите в профиль пользователя в правом верхнем углу.
3. Перейдите в раздел **SSH-ключи**.
4. Выберите нужный ключ.
5. Нажмите на &hellip; и выберите **Редактировать**.
6. Измените имя ключа.
7. Нажмите **Сохранить**.
## Удалить SSH-ключ
1. Войдите в [личный кабинет](https://lk.cloud.beeline.ru/).
2. Перейдите в профиль пользователя в правом верхнем углу.
3. Перейдите в раздел **SSH-ключи**.
4. Выберите нужный ключ.
5. Нажмите на &hellip; и выберите **Удалить**.
6. Нажмите **Удалить**, чтобы подтвердить удаление ключа.
+178
View File
@@ -0,0 +1,178 @@
# Чат с LLM
**Чат с LLM** - это интерфейс для общения с LLM-моделями. Подходит для знакомства и тестирования моделей.
Исходя из возможностей сервиса Чат с LLM пользовательский путь от авторизации к диалогу выглядит следующим образом:
1. Переход в чат с LLM.
2. Выбор LLM.
3. Выбор базы знаний.
4. Настройка системного промпта.
5. Диалог с LLM.
## Доступные модели
Чат с LLM поддерживает модели:.
| Модель | Контекст | Параметры | Reasoning | Инструменты | Картинки |
|:-------|:-------|:-------|:-------|:-------|:-------|
| Deepseek-chat | 131k | 671B | ✅ | ✅ | ❌ |
| Gemma 3 | 128k | 27B | ❌ | ❌ | ✅ |
| Qwen 3 | 131k | 32B | ✅ |✅ | ❌|
::: details Описание моделей
- **DeepSeek Chat**
DeepSeek V3 — это мощная гибридная модель с 671 млрд. параметров, специально оптимизированная для кодогенерации и работы поисковых агентов. Модель поддерживает контекст до 128 тыс. токенов и позволяет гибко управлять режимом рассуждений через параметр "reasoning_enabled". Она демонстрирует производительность уровня DeepSeek-R1, но работает быстрее, идеально подходя для программирования, исследований и агентных workflow.
- **Gemma 3**
Основная особенность этой модели в том, что она поддерживает картинки. Вы можете использовать ее как OCR: модель распознает рукописный текст на русском языке. Кроме этого, модель распознает и классифицирует объекты на фотографиях; может распознавать и переводить надписи.
- **Qwen 3 32B**
Основная модель, с которой рекомендуется начинать эксперименты. Поддерживает нативный вызов инструментов.
Режимы работы:
- с рассуждениями (включен по умолчанию).
- без рассуждений (нужно передать в запросе /no_think).
:::
## Авторизация в чате с LLM
Доступ к чату с LLM-моделями предоставляется по уникальной ссылке, которая формируется после [создания тенанта](ai-setting.md#создать-тенант).
1. В левом меню откройте раздел **Тенанты**.
2. Нажмите на имя тенанта.
3. Из поля **Url приложения** скопируйте ссылку на чат с LLM.
4. Вставьте ссылку в браузер. Откроется чат с LLM.
![alt text](./image/Chat_AI_Main_1024.png)
::: details Интерфейс чата с LLM
- **Чат**
Раздел включает функции:
- диалог с моделью в режиме вопрос-ответ;
- выбор LLM;
- выбор базы знаний.
- **Базы знаний**
Раздел предназначен для подготовки базы знаний, на основе которой модель будет генерировать ответы.
- **Системные промпты**
Раздел предназначен для создания системных промптов. Системный промпт представляет из себя набор инструкций, на которые опирается модель при подготовке ответа на запрос пользователя.
:::
## Начать диалог с моделью
1. [Авторизоваться в чате с LLM](#авторизация-в-чате-с-llm).
2. В левом меню выберите раздел **Чаты**.
3. Выберите из списка модель. Если в списке отсутствует нужная [модель](#доступные-модели), то [добавьте модель](ai-setting.md#добавить-модель) в тенант.
::: tip Информация
Эксперименты рекомендуется с модели **Qwen 3 32B**, которая имеет больший контекст и поддерживает нативный вызов инструментов.
Модель **Qwen 3 32B** может работать:
- [с рассуждениями](ai-glossary.md#рассуждения) - этот режим включен по умолчанию;
- без рассуждений - в этом случае нужно передать в запросе `/no_think`.
:::
4. (опционально) Выберите базу знаний, на основе которой модель составит ответ. Если список баз данных пуст, то [создайте](#создать-базу-знаний) базу знаний.
5. (опциоанльно) Выберите системный промпт. По умолчанию в чате задан системный промпт. Если необходим промпт под определенную задачу, то [измените](#редактировать-системный-промпт) системный промпт.
6. Введите запрос к модели. Дождитесь ответа.
## Использовать базу знаний
Если необходимо, чтобы модель генерировала ответы не на базе своего раннего обучения, а обращалась, например, к актуальной нормативной базе или актуальным тарифам, то необходимо указать [базу знаний](ai-glossary.md#база-знаний-rag), с которой чат должен расширить свой контекст.
Для этого необходимо выбрать базу знаний и продолжить диалог.
![alt text](./image/Chat_AI_Choice_RAG_SalesHelper_1024.png)
Если база знаний отсутствует в списке, то [создайте](#создать-базу-знаний) базу знаний и добавьте документы.
### Создать базу знаний
1. [Авторизоваться в чате с LLM](#авторизация-в-чате-с-llm).
2. В левом меню выберите раздел **Базы знаний**.
3. Нажмите кнопку **Создать базу знаний**.
4. Заполните параметры базы знаний:
- **Имя**: введите имя базы знаний, имя будет отображаться при выборе базы знаний в чате.
- **Описание**: введите описание базы знаний.
5. Нажмите кнопку **Создать**.
База знаний будет создана, но в ней пока нет информации для генерации ответов модели. Добавьте документы в базу знаний.
### Добавить документ в базу знаний
1. [Авторизоваться в чате с LLM](#авторизация-в-чате-с-llm).
2. В левом меню выберите раздел **Базы знаний**.
3. В списке нажмите на нужную базу знаний.
4. Нажмите кнопку **Добавить документ**.
5. Загрузите файлы в базу знаний.
6. Нажмите **Добавить**.
## Редактировать системный промпт
По умолчанию задан простой "размытый" [промпт](ai-glossary.md#промпт), который указывает, что ответы модели должны быть полезными. Но такой чат не всегда сможет предоставить пользователю ответ, который его устроит.
В чате с LLM доступен редактор системных промптов. Возможны способы редактирования системных промптов:
- редактирование системного промпта в текущей сессии диалога с моделью;
- создание системного промпта в библиотеке системных промптов для дальнейшего использования.
### Редактирование системного промпта в текущей сессии
1. [Начните](#начать-диалог-с-моделью) диалог с моделью.
2. Системный промпт отображается над строкой для ввода текста в чате.
3. Нажмите на значок карандаша справа от системного промпта.
4. В появившемся окне справа введите содержимое промпта.
5. Нажмите кнопку **Сохранить**.
6. Содержимое системного промпта обновится.
Редактируемый системный промпт доступен для всех моделей и сохраняется только в рамках текущей сессии.
### Создать системный промпт
1. [Авторизоваться в чате с LLM](#авторизация-в-чате-с-llm).
2. В левом меню выберите раздел **Системные промпты**.
3. Нажмите кнопку **Создать системный промпт**.
4. Заполните параметры промпта:
- **Название**: введите название системного промпта.
- **Содержание**: введите содержание промпта.
5. Нажмите **Создать**.
Системный промпт добавлен в библиотеку системных промптов. Посмотреть список промптов можно в левом меню в разделе **Системные промпты**.
## Сменить тенант
В чате с LLM-моделями есть возможность работать сразу с несколькими [тенантами](ai-setting.md#создать-тенант).
Для смены текущего тенанта необходимо:
1. В верхнем меню нажмите на вкладку **Тенант**.
2. Выберите из списка тенант.
К тенанта привязаны сущности:
- модели;
- базы знаний;
- системные промпты.
Для каждого тенанта эти сущности будут отличаться.
## Очистить контекст диалога
При длительном диалоге модель накапливает [контекст](ai-glossary.md#контекст) и может начать генерировать неточные ответы ("галлюцинации"). Для предотвращения "галлюцинации" рекомендуется периодически очищать контекст диалога.
Для очистки контекста диалога нажмите на значок корзины в правом верхнем углу окна чата.
+51
View File
@@ -0,0 +1,51 @@
# Быстрый старт с AI платформа
Данная инструкция рассматривает начальную настройку сервиса **AI платформа** и отправку первого запроса к LLM-модели.
## Перед началом работы
- [Зарегистрируйтесь](../start/getting-started.md#1-регистрация-в-beeline-cloud) в личном кабинете Beeline Cloud.
## 1. Создать тенант
1. В верхнем меню нажмите на пункт **Сервисы**.
2. Выберите **Сервис AI платфома**.
3. В левом меню откройте раздел **Тенанты**.
4. Нажмите кнопку **Создать тенант**.
5. Введите имя тенанта.
6. Нажмите **Создать тенант**.
## 2. Добавить модель
1. В левом меню откройте раздел **Модель**.
2. Нажмите кнопку **Добавить модель**.
3. В поле **Тенант** выберите созданный тенант.
4. В поле **Модель** выберите из списка подходящую **LLM-модель**.
5. Установите лимит использования токенов в час.
6. Нажмите **Добавить модель**.
## 3. Перейти в чат с LLM
Протестировать модели в интерфейсе можно в чате с LLM. Доступ к чату с LLM-моделями предоставляется по уникальной ссылке, которая формируется после создания тенанта.
1. В левом меню откройте раздел **Тенанты**.
2. Нажмите на имя тенанта.
3. Из поля **Url приложения** скопируйте ссылку на чат с LLM.
4. Вставьте ссылку в браузер.
## 4. Создать системный промпт
1. В чате с LLM в левом меню откройте раздел **Системные промпты**.
2. Нажмите кнопку **Создать системный промпт**.
3. Заполните параметры промпта:
- **Название**: введите название систменого промпта;
- **Содержание**: введите содержание промпта.
4. Нажмите **Создать**.
## 5. Начать диалог с моделью
1. В чате с LLM-моделями в левом меню перейдите в раздел **Чат**.
2. Выберите из списка модель.
3. Выберите из списка системный промпт.
4. Откроется чат. В текстовом поле внизу введите запрос к LLM-модели.
5. Дождитесь ответа модели.
+26
View File
@@ -0,0 +1,26 @@
# Концепции
## База знаний (RAG)
RAG — это подход, при котором ответ LLM формируется с использованием дополнительного источника актуальных данных.
## Контекст
Контекст — это ограниченное по размеру окно, в которое должен уместиться запрос к LLM. У каждой модели контекст строго ограничен и указан в документации к ней.
## Рассуждения
Reasoning (рассуждение или логическое мышление) у LLM — это способность модели не просто воспроизводить выученные паттерны текста, а последовательно и логически выводить новую информацию из уже известных ей данных.
## Промпт
Промпт — это текстовый запрос, который вы отправляете модели, и который задает контекст и направление для ответа. LLM анализирует промпт и генерирует ответ, который является логическим продолжением текста. Чем понятнее и конкретнее сформулирован промпт, тем качественнее будет ответ.
Системные промпты — специальные инструкции, которые задают общие рамки поведения модели на протяжении всего диалога. Системный промпт устанавливается в начале общения и сообщает модели, какую роль она должна играть, какие ограничения соблюдать и какой стиль общения использовать.
В сервисе **AI-платформа** системный промпт доступен для редактирования, чтобы пользователи могли максимально настраивать поведение моделей.
## Токен
LLM представляет текст не в виде слов или букв, а в виде токенов. Токен — это несколько букв (часть слова), которые часто встречаются рядом в обучающей выборке. Текст запроса, который вы отправляете в LLM, сначала нарезается на токены, и только потом обрабатывается моделью.
+11
View File
@@ -0,0 +1,11 @@
# Обзор сервиса
Сервис **AI платфома** предоставляет доступ к большим языковым моделям (Large Language Models, LLM). LLM-модели готовы к использованию и избавляют пользователя от необходимости самостоятельного развертывания и изучения связанных технологий.
## Возможности сервиса
- Интерфейс для взаимодействия с моделями в формате чат-бота.
- Предоставляет различные [модели](ai-chat-llm.md#доступные-модели).
- Использование баз знаний (RAG).
- Редактирование системного промпта.
- Диалог с моделью.
+56
View File
@@ -0,0 +1,56 @@
# Управление сервисом
В разделе рассмотрены компоненты сервиса **AI платформа** и приведены пошаговые инструкции по их созданию и управлению компонентами.
## Создать тенант
**Тенант** представляет собой изолированный логический контейнер ресурсов сервиса (модели, базы знаний) для работы в рамках проекта. Создается в личном кабинете Beeline Cloud.
1. Войдите в [личный кабинет](https://lk.cloud.beeline.ru/).
2. В верхнем меню нажмите на раздел **Сервисы**.
3. Выберите **Сервис AI платформа**.
4. В левом меню откройте раздел **Тенанты**.
5. Нажмите кнопку **Создать тенант**.
6. Введите имя тенанта.
7. Нажмите **Создать тенант**.
## Добавить модель
1. Войдите в [личный кабинет](https://lk.cloud.beeline.ru/).
2. В верхнем меню нажмите на раздел **Сервисы**.
3. Выберите **Сервис AI платформа**.
4. В левом меню откройте раздел **Модели**.
5. Нажмите кнопку **Добавить модель**.
6. Заполните параметры модели:
- **Тенант**: выберите тенант, в котором будет использоваться модель.
- **Модель**: выберите из списка подходящую LLM-модель.
- **Токены**: введите лимит использования токенов в час.
7. Нажмите кнопку **Добавить модель**.
## Добавить базу знаний
1. Войдите в [личный кабинет](https://lk.cloud.beeline.ru/).
2. В верхнем меню нажмите на раздел **Сервисы**.
3. Выберите **Сервис AI платформа**.
4. В левом меню откройте раздел **База знаний**.
5. Нажмите кнопку **Создать базу знаний**.
6. Заполните параметры базы знаний:
- **Тенант**: выберите из списка тенант.
- **Имя**: введите имя базы знаний.
- **Описание**: введите описание базы знаний.
7. Нажмите **Создать базу знаний**.
[Наполнение базы знаний](ai-chat-llm.md#добавить-документ-в-базу-знаний) документами, на основании которых будет генерироваться ответ модели, выполняется в чате с LLM.
## Удалить тенант, модель, базу знаний
1. Войдите в [личный кабинет](https://lk.cloud.beeline.ru/).
2. В верхнем меню нажмите на раздел **Сервисы**.
3. Выберите **Сервис AI платформа**.
4. Откройте раздел c нужным компонентом сервиса:
- **Тенанты**,
- **Модели**,
- **Базы знаний**.
5. В таблице найдите строку с нужным компонентом сервиса.
6. Нажмите &hellip; и выберите **Удалить**.
7. В открывшемся окне подтвердите операцию, нажав **Удалить**.
Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

+21
View File
@@ -0,0 +1,21 @@
---
section_links:
- title: Обзор сервиса
link: /ai/ai-overview-platform.md
description: Обзор сервиса, решаемые задачи
- title: Быстрый старт
link: /ai/ai-getting-started.md
description: Создание виртуальной машины в дата-центре
- title: Настройка сервиса
link: /ai/ai-setting.md
description: Создание тенанта, добавление моделей и базы знаний
- title: Чат с LLM
link: /ai/ai-chat-llm.md
description: Интерфейс для взаимодействия с LLM-моделями в формате чат-бота
- title: Концепции
link: /ai/ai-glossary.md
description: Основные понятия, используемые в сервисе
---
# AI платформа
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More