Дом настроек
Единый каркас всех экранов настроек: объект, дерево разделов, секции и панель сохранения. Дом решает, что показать, каркас — как.
Когда использовать#
- У объекта — проекта, команды, учётной записи — есть настройки, и их больше одной формы.
- Настройки делятся на разделы: общее, доступ, ключи, история.
- Каждая группа полей сохраняется отдельно и проверяется отдельно.
Для одной короткой формы дом не нужен: хватит полей и кнопки в карточке.
Устройство#
Дом — узел Кит.ДомНастроек(Заголовок, Адрес, Токен, секции…). Слева — разделы дома деревом, справа — секции текущего раздела. Разделы объявляет слово Раздел(Подпись, Ключ, Иконка): адрес раздела — адрес дома, косая черта и ключ; пустой ключ — адрес самого дома, ключ с ведущей косой — адрес как есть. Текущий раздел помечает слово Текущий().
Секции — дети дома, узлы Кит.Секция(Заголовок, тело…). Секция-форма печатается своей формой со своей панелью сохранения: секция — единица переноса, у неё своя проверка и свой POST.
Разделы, секции и шторка узкого экрана
Настройкиальфа
Что видит участник проекта
Общее
Имя проекта
Видно всем участникам
Дом = Кит.ДомНастроек("Настройки", "/настройки", "т0кен-сессии",
Кит.Секция("Имя проекта", Кит.Поле("имя", "Имя").Значение("альфа"))
.Лид("Видно всем участникам").Форма())
.Ключ("project").Объект("альфа").Пояснение("Что видит участник проекта");
Дом.Раздел("Общее", "", "шестерёнка").Текущий();
Дом.Раздел("Доступ", "доступ", "замок");
Дом.Раздел("Ключи", "ключи", "ключ");
Дом.Раздел("История", "история", "история");
HTML = Дом.Рендер();Рубрики и опасный раздел#
Длинный дом читается группами. Слово дома Рубрика(Подпись) ставит подпись над следующими разделами: все Раздел(…) после неё, до следующей рубрики, встают под неё. Рубрика("") заканчивает группу. Разделы не переставляются — порядок остаётся тот, в котором их объявил дом.
Раздел необратимого — удаление, передача — помечает слово раздела Опасный(). Он печатается цветом ошибки, значок тоже, и всегда стоит последним и без рубрики, где бы его ни объявили: необратимое не должно стоять между обычными разделами. Слово Счётчик(Число, Подпись) ставит число у пункта раздела в едином меню — например, сколько заявок ждёт ответа.
Три рубрики и опасный раздел
Настройки проектаальфа
Участники
Участники
Пригласите коллег по почте.
Дом = Кит.ДомНастроек("Настройки проекта", "/проекты/альфа/настройки", "т0кен-сессии",
Кит.Секция("Участники", Кит.Примечание("Пригласите коллег по почте.")))
.Ключ("project").Объект("альфа");
Дом.Раздел("Общее", "", "шестерёнка");
Дом.Рубрика("Доступ");
Дом.Раздел("Участники", "участники", "аккаунт").Текущий().Счётчик(2, "2 заявки");
Дом.Раздел("Ключи", "ключи", "ключ");
Дом.Рубрика("Оповещения");
Дом.Раздел("Почта", "почта", "конверт");
Дом.Рубрика("Журнал");
Дом.Раздел("История", "история", "история");
Дом.Раздел("Удаление", "удаление", "корзина").Опасный();
HTML = Дом.Рендер();На телефоне#
Меню на телефоне одно — бургер единого меню. Разделы дома встают в его шторку первой группой, сразу под учёткой: заголовок группы — имя дома, внутри те же рубрики и пункты, что в колонке, текущий раздел залит, опасный — цветом ошибки. Остальные группы шторки — дороги приложения, дела, тема и выход — идут ниже и не двигаются от страницы к странице. Колонка разделов на странице прячется: второго меню рядом с бургером нет.
Чтобы было видно, где человек стоит, под заголовком дома печатается имя и значок текущего раздела — строкой settings__current, а не ссылкой. На широком экране эта строка скрыта: там колонка разделов с подсвеченным пунктом, а в выпадающем меню у кнопки-учётки группы разделов нет. Всё это делает лист стилей, скрипта здесь нет.
Если единого меню у приложения нет, на телефоне колонка разделов встаёт над секциями и читается пальцем, а строка с именем раздела не нужна и скрыта.
Каркас страницы берёт разделы для меню у самого дома, когда содержимое страницы — дом: передавать их вторым аргументом незачем. Группу он называет заголовком дома.
Дом = Кит.ДомНастроек("Настройки проекта", "/проекты/альфа/настройки", Токен, Секции…);
Дом.Раздел("Общее", "").Текущий();
Ответ.ТелоТекст = Каркас.Страница("Настройки проекта", Дом, Контекст);
Имя текущего раздела под заголовком — на телефоне с единым меню
Настройки проектаальфа
Ключи
Ключи
Ключей пока нет.
Дом = Кит.ДомНастроек("Настройки проекта", "/проекты/альфа/настройки", "т0кен-сессии",
Кит.Секция("Ключи", Кит.Примечание("Ключей пока нет.").Вид("пусто")))
.Ключ("project").Объект("альфа");
Дом.Раздел("Общее", "", "шестерёнка");
Дом.Раздел("Ключи", "ключи", "ключ").Текущий();
HTML = Дом.Рендер();Сузьте окно этого сайта до телефона: у образца выше колонка разделов спрячется, а под заголовком встанет «Ключи» со значком — у сайта есть единое меню.
Дом без разделов — ни колонки, ни шторки
Настройки
Единственная секция
прятать нечего: разделов у дома нет
HTML = Кит.ДомНастроек("Настройки", "/настройки", "",
Кит.Секция("Единственная секция", Кит.Примечание("прятать нечего: разделов у дома нет")))
.Ключ("project").Рендер();Над шапкой дома — крошки, над секциями — уведомления: слова Крошка(Подпись, Адрес) и Уведомление(узел или текст). Крошки печатает компонент «Крошки»: последняя — текущая страница, текстом и без ссылки. Слово Пояснение необязательно: у короткого дома его нет, и пустого абзаца под заголовком тоже нет.
Крошки и уведомление над секциями
HTML = Кит.ДомНастроек("Ключи доступа", "/проекты/альфа/ключи", "т0кен-сессии",
Кит.Секция("Ключи", Кит.Примечание("Ключей пока нет.").Вид("пусто")))
.Ключ("project")
.Крошка("Проекты", "/проекты").Крошка("альфа", "/проекты/альфа").Крошка("Ключи")
.Уведомление(Кит.Уведомление("Ключ отозван").Вид("warn"))
.Рендер();Адрес и токен — у дома#
Адрес раздела и CSRF-токен задаются один раз — у дома. Секция-форма и любая форма внутри берут их у ближайшего предка:
Секция.Форма()— форма на адрес текущего раздела,Секция.Форма("описание")— нараздел/описание,Секция.Форма("/x")— на свой адрес;Кит.Форма("", …),Кит.Форма("revoke", …),Кит.Форма("/x", …)внутри секции — по тем же правилам.
Форма без токена ни у себя, ни у предков не печатается: она выглядела бы рабочей, а получала 403.
Секция сохраняется своей формой
Настройки
Описание
Короткий текст под именем проекта
HTML = Кит.ДомНастроек("Настройки", "/настройки", "т0кен-сессии",
Кит.Секция("Описание",
Кит.Поле("описание", "Описание").Многострочное().Значение("Отчёты команды аналитики"))
.Лид("Короткий текст под именем проекта")
.Форма("описание").ПояснениеПанели("Изменения увидят все участники"))
.Ключ("project").Рендер();Секция без формы — витрина или список, где у каждой строки своя маленькая форма. Строки таблицы из данных находят адрес и токен дома так же, как дети секции.
Секция-список: у каждой строки своя форма
Настройки
Ключи
Мои ключи
| Имя | Действие |
|---|---|
| ноутбук | |
| сборка |
Ключи = Новый ТаблицаЗначений;
Ключи.Колонки.Добавить("Имя");
Ключи.Колонки.Добавить("Действие");
Для Каждого Имя Из СтрРазделить("ноутбук,сборка", ",") Цикл
Ключ = Ключи.Добавить();
Ключ.Имя = Имя;
Ключ.Действие = Кит.Форма(Имя + "/отзыв", Кит.Кнопка("Отозвать").Опасная().Малая());
КонецЦикла;
Дом = Кит.ДомНастроек("Настройки", "/проекты/альфа/настройки", "т0кен-сессии",
Кит.Секция("Мои ключи", Кит.Таблица(Ключи).Пусто("Ключей пока нет.")).Иконка("ключ"))
.Ключ("project");
Дом.Раздел("Ключи", "ключи").Текущий();
HTML = Дом.Рендер();Действия секции#
Кнопка, которая добавляет запись в список секции, стоит в одном месте на всех экранах — справа от заголовка и лида секции, по верху. Её кладут во второй холст секции Действия(д…): кнопки, ссылки-кнопки или маленькую форму с одной кнопкой. Форма в слоте берёт адрес и токен у дома, как и форма в теле секции. На узком экране (до 640 px) слот встаёт под лидом во всю ширину, и кнопка растягивается.
Кнопка «Добавить» справа от заголовка
Настройки
Ключи
Мои ключи
Ключом участник входит без пароля
| Имя | Создан |
|---|---|
| ноутбук | 12 марта |
Ключи = Новый ТаблицаЗначений;
Ключи.Колонки.Добавить("Имя");
Ключи.Колонки.Добавить("Создан");
Ключ = Ключи.Добавить();
Ключ.Имя = "ноутбук";
Ключ.Создан = "12 марта";
Дом = Кит.ДомНастроек("Настройки", "/проекты/альфа/настройки", "т0кен-сессии",
Кит.Секция("Мои ключи", Кит.Таблица(Ключи).Пусто("Ключей пока нет."))
.Лид("Ключом участник входит без пароля")
.Действия(Кит.Форма("новый", Кит.Кнопка("Добавить ключ").Основная().Иконка("ключ"))))
.Ключ("project");
Дом.Раздел("Ключи", "ключи").Текущий();
HTML = Дом.Рендер();Пустой слот не печатается вовсе: у секции без действий шапка та же, что и раньше. В прежнем виде модели слот — поле Действия структуры секции: массив моделей кнопок или готовая разметка строкой.
Действия структурой — прежний вид модели
Участники
Кто работает над проектом
Пока в проекте только вы.
Действия = Новый Массив();
Действия.Добавить(Новый Структура("Подпись, Адрес, Вариант", "Пригласить", "/участники/новый", "вторичная"));
Секция = Настройки.Секция("Участники", "Кто работает над проектом",
Кит.Примечание("Пока в проекте только вы.").Рендер());
Секция.Действия = Действия;
HTML = Настройки.ОтрисоватьСекцию(Секция);Опасная секция
Настройки
Удаление
Проект и все его документы будут удалены
Удалить проект
Отменить это нельзя.
HTML = Кит.ДомНастроек("Настройки", "/настройки", "",
Кит.Секция("Удаление",
Кит.ОпаснаяЗона("Удалить проект").Пояснение("Отменить это нельзя.")
.Подтверждение("подтверждение", "альфа"))
.Лид("Проект и все его документы будут удалены").Опасная().БезПанели())
.Ключ("project").Рендер();Секция, которую открывают редко, уходит под кат целиком словом Свёрнута(ПодписьРаскрытия); Раскрыта() печатает кат открытым — так отбитая форма возвращается человеку.
Свёрнутая секция-форма
Настройки
Передача проекта
Передать проект другому участнику
HTML = Кит.ДомНастроек("Настройки", "/настройки", "т0кен-сессии",
Кит.Секция("Передача проекта", Кит.Поле("кому", "Новый владелец"))
.Форма("передача").Свёрнута("Передать проект другому участнику").Кнопка("Передать"))
.Ключ("project").Рендер();Секция вне дома#
Секция печатается и сама — тем же каркасом, что внутри дома. Секции-форме вне дома нужен свой адрес от корня, токен она берёт у предков.
Секция вне дома
Почта для писем
HTML = Кит.Холст(
Кит.Секция("Почта для писем", Кит.Поле("почта", "Почта").ТипЗначения("email"))
.Форма("/учётка/почта")).Токен("т0кен-сессии").Рендер();Прежний вид модели#
Настройки.Отрисовать(Модель) со структурой дома, Настройки.Раздел и Настройки.Секция работают как раньше и печатают ту же разметку, что дом из узлов.
Дом структурой — прежний вид модели
Настройки
Описание
Короткий текст под именем проекта
Секция = Настройки.Секция("Описание", "Короткий текст под именем проекта",
Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип, Значение",
"описание", "Описание", "многострочное", "Отчёты команды аналитики")));
Секция.Действие = "/настройки/описание";
Секция.Токен = "т0кен-сессии";
Секция.ПояснениеПанели = "Изменения увидят все участники";
Секции = Новый Массив();
Секции.Добавить(Секция);
HTML = Настройки.Отрисовать(Новый Структура("Ключ, Заголовок, Секции",
"project", "Настройки", Секции));Гайдлайны#
Настройки
Имя проекта
Ключ доступа
Код
HTML = Кит.ДомНастроек("Настройки", "/настройки", "т",
Кит.Секция("Имя проекта", Кит.Поле("имя", "Имя").Значение("альфа")).Форма("имя"),
Кит.Секция("Ключ доступа", Кит.Поле("ключ", "Ключ доступа")).Форма("ключ"))
.Ключ("project").Рендер();Настройки
Всё сразу
Код
HTML = Кит.ДомНастроек("Настройки", "/настройки", "т",
Кит.Секция("Всё сразу",
Кит.Поле("имя", "Имя"),
Кит.Поле("ключ", "Ключ доступа"),
Кит.Поле("почта", "Почта для писем")).Форма())
.Ключ("project").Рендер();Доступность#
- Колонка разделов — навигация с подписью из словаря инсталляции (
settings.frame.nav.title); текущий раздел помеченaria-current. Рубрика — строка списка с текстом, а не ссылка: скринридер читает её на своём месте, перед разделами группы. - Опасный раздел отличается не только цветом: он стоит последним, а его подпись говорит, что он делает («Удаление»).
- Строка с именем текущего раздела — обычный абзац: она отвечает на «где я» и в порядок обхода клавиатурой не встаёт.
- Секция —
<section>с заголовком: скринридер ходит по секциям, как по главам. - Ключ дома пишется латиницей: он уходит в атрибут
data-house, а имена атрибутов кит пропускает только из[a-z0-9-].
Справка#
Кит.ДомНастроек()src/Классы/холст/Кит.os
Дом настроек — объект, разделы колонкой слева и секции справа; печатается каркасом
настроек (РендерерНастроек) — разметка та же, что у модели-структуры. Адрес и токен
задаются один раз здесь: секции-формы и формы внутри берут их у дома. Дети — секции
(Кит.Секция); разделы — словом Раздел(Подпись, Ключ, Иконка), рубрики над ними — словом
Рубрика(Подпись). Слова: Ключ (латиницей, data-house), Объект, Пояснение,
Крошка(Подпись, Адрес), Уведомление(узел | текст), Рубрика, Раздел.
Параметры:
Заголовок - Строка - заголовок дома.
Адрес - Строка - адрес дома; адрес раздела — Адрес/Ключ.
Токен - Строка, ЭлементЭкрана - (необязательный) CSRF-токен сессии; узел на этом
месте — первая секция.
Р1…Р7 - ЭлементЭкрана - (необязательные) секции.
Возвращаемое значение:
ЭлементЭкранаКит.Секция()src/Классы/холст/Кит.os
Секция настроек — карточка с заголовком; её тело — дети узла, кнопки справа от заголовка — второй холст Действия(д…) (на узком экране он встаёт под лидом). Внутри дома и вне его печатается тем же каркасом. Словом Форма(Хвост) становится формой со своей панелью сохранения: адрес — у контекста, токен — у предков. Слова: Лид, Иконка, Форма, Кнопка, ИконкаКнопки, ИмяКнопки(Имя, Значение), ПояснениеПанели, АдресОтмены, Опасная, Заблокирована, БезПанели, СФайлами, Свёрнута(ПодписьРаскрытия), Раскрыта, Якорь. Параметры: Заголовок - Строка - заголовок секции. Р1…Р8 - ЭлементЭкрана, Строка - (необязательные) тело секции; строка — текст. Возвращаемое значение: ЭлементЭкрана
ЭлементЭкрана.Раздел()src/Классы/холст/ЭлементЭкрана.os
Раздел дома настроек: строка в колонке разделов. Адрес раздела — адрес дома, косая черта и ключ; ключ с ведущей косой берётся адресом как есть, пустой — адрес самого дома. Раздел попадает под рубрику, объявленную словом Рубрика дома до него. Параметры: Подпись - Строка - название раздела. Ключ - Строка - хвост адреса раздела. Иконка - Строка - (необязательный) имя иконки. Возвращаемое значение: ЭлементЭкрана - узел раздела: слова Текущий(), Опасный(), Счётчик(Число, Подпись).
ЭлементЭкрана.Текущий()src/Классы/холст/ЭлементЭкрана.os
Раздел дома — тот, что открыт: он помечен в колонке разделов, и его адрес — адрес контекста для форм дома. Шаг формы (Кит.Шаг) — тот, с которого шаги начинаются: открыт без скрипта и текущий со скриптом, если ни у одного поля нет ошибки. Возвращаемое значение: ЭлементЭкрана - этот же элемент.
ЭлементЭкрана.Рубрика()src/Классы/холст/ЭлементЭкрана.os
Рубрика дома: все разделы, объявленные словом Раздел после неё, — до следующей рубрики — встают под эту подпись в колонке разделов и в группе разделов единого меню. Пустая подпись заканчивает рубрику: следующие разделы идут без неё. Параметры: Подпись_ - Строка - подпись рубрики. Возвращаемое значение: ЭлементЭкрана - этот же дом.
ЭлементЭкрана.Опасный()src/Классы/холст/ЭлементЭкрана.os
Раздел необратимого (удаление, передача): цветом ошибки, значок тоже, всегда последним и без рубрики — где бы его ни объявили. Параметры: Флаг - Булево - (необязательный, по умолчанию Истина) Возвращаемое значение: ЭлементЭкрана - этот же раздел.
Кит.ЗаголовокДома()src/Классы/холст/Кит.os
Заголовок дома — им каркас страницы подписывает группу разделов дома в едином меню. Параметры: Дом - ЭлементЭкрана - узел Кит.ДомНастроек. Возвращаемое значение: Строка
ЭлементЭкрана.Форма()src/Классы/холст/ЭлементЭкрана.os
Секция становится формой со своей панелью сохранения; окно — формой целиком (кнопки действий отправляют её сами). Адрес — адрес контекста (раздел дома) с хвостом: пустой хвост — сам адрес, «x» — адрес/x, «/x» — абсолютный адрес. Токен берётся у предков. Параметры: Хвост - Строка - (необязательный) хвост адреса. Возвращаемое значение: ЭлементЭкрана - этот же элемент.
ЭлементЭкрана.Действия()src/Классы/холст/ЭлементЭкрана.os
Действия — второй холст: кнопки и формы. У карточки они печатаются под её телом, у секции настроек — справа от заголовка и лида (на узком экране — под лидом). Параметры: Р1 - ЭлементЭкрана, Строка, Неопределено - (необязательный) действия, до Р8. Р2 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р3 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р4 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р5 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р6 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р7 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р8 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Возвращаемое значение: ЭлементЭкрана - без аргументов холст действий; с аргументами — эта карточка или секция.
Кит.РазделыДома()src/Классы/холст/Кит.os
Разделы дома для единого меню — та же форма, что у РендерерНастроек.Раздел: каркас
страницы берёт их отсюда, когда содержимое страницы — дом.
Параметры:
Дом - ЭлементЭкрана - узел Кит.ДомНастроек.
Возвращаемое значение:
Массив из Структура - Подпись, Адрес, Иконка, Активен, Рубрика, Опасный, Счётчик,
ПодписьСчётчика.РендерерНастроек.Отрисовать()src/Классы/каркас/РендерерНастроек.os
Отрисовывает дом настроек.
Параметры:
Модель - Структура - Ключ дома ЛАТИНИЦЕЙ ("account", "project", "team"):
он идёт в data-house, а ЭкранированиеHTML отбрасывает имена атрибутов вне
[a-z0-9-]; Заголовок, Объект (имя настраиваемого объекта), Пояснение,
Разделы (модель ДеревоРазделов, см. Раздел), Уведомления (структуры Текст,
Вид для компонента «Тост»), Секции (см. Секция), Хлебные (структуры
Подпись, Адрес — печатаются компонентом «Крошки»: последняя крошка — текущая
страница, без ссылки). Пояснение необязательно: без него абзаца под
заголовком нет вовсе.
Возвращаемое значение:
Строка - HTML-фрагмент для <main>. Под заголовком дома, у которого есть текущий
раздел, стоит его имя и значок (settings__current): на телефоне колонку
разделов заменяет единое меню, и страница сама говорит, где стоит человек.РендерерНастроек.Раздел()src/Классы/каркас/РендерерНастроек.os
Заготовка раздела дерева для модели дома. Поля Рубрика и Опасный стоят в структуре
всегда, поэтому их можно дописать и у готового результата.
Параметры:
Подпись - Строка - название раздела.
Адрес - Строка - URL раздела.
Иконка - Строка - (необязательный, по умолчанию "") имя иконки.
Активен - Булево - (необязательный, по умолчанию Ложь) текущий раздел.
Рубрика - Строка - (необязательный, по умолчанию "") подпись над первым разделом
с этим именем рубрики.
Опасный - Булево - (необязательный, по умолчанию Ложь) раздел необратимого: цветом
ошибки, последним и без рубрики.
Возвращаемое значение:
Структура - раздел для ДеревоРазделов: Подпись, Адрес, Иконка, Активен, Рубрика, Опасный.РендерерНастроек.Секция()src/Классы/каркас/РендерерНастроек.os
Заготовка секции. Поля дозаполняются у результата — структура открытая.
Параметры:
Заголовок - Строка - заголовок секции.
Пояснение - Строка - (необязательный, по умолчанию "") что настраивает секция.
Тело - Строка - (необязательный, по умолчанию "") ДОВЕРЕННЫЙ HTML содержимого.
Возвращаемое значение:
Структура - секция со всеми известными каркасу полями: Действие (URL POST; задан —
секция становится <form>), Токен (CSRF-токен, обязателен при Действии),
Кнопка, ИконкаКнопки (пусто — «сохранить»), ИмяКнопки и ЗначениеКнопки
(name/value кнопки панели: форма с двумя кнопками отличает нажатую),
АдресОтмены, ПояснениеПанели, Опасная, Заблокирована, БезПанели
(кнопки внутри тела), Иконка, Класс, Якорь, СФайлами (форма секции
получает enctype составной формы — без него браузер шлёт одни имена
файлов вместо содержимого), Свёрнута (секция уходит под кат целиком),
ПодписьРаскрытия (обязательна у свёрнутой), Раскрыта (кат печатается
открытым — так возвращается отбитая форма) и Действия (кнопки справа от
заголовка и лида: массив моделей компонента «Кнопка» либо ДОВЕРЕННЫЙ HTML
строкой; пусто — слота нет вовсе).РендерерНастроек.ОтрисоватьСекцию()src/Классы/каркас/РендерерНастроек.os
Отрисовывает одну секцию — та же разметка, что секция внутри дома: карточка-<section>, своя форма с CSRF-полем и панелью сохранения, когда у секции есть Действие. Так секция печатается и вне дома настроек. Параметры: ОписаниеСекции - Структура - секция (см. Секция). Возвращаемое значение: Строка - HTML-фрагмент <section>.