Завершение настройки карточки¶
Теперь можно перейти на вкладку Карточки и закончить разработку типа карточки AbDocument
.
Дополнительные контролы¶
В карточке не хватает контрола с заголовком Partner
типа Ссылка
для ссылки на контрагента из стандартного справочника контрагентов. Он связывается с полем карточки AbDocuments.Partner
.
Алиас представления: Partners
Алиас параметра: Name
(т.е. стандартное представление со списком контрагентов)
Остальные свойства будут иметь значения по умолчанию.
Также необходимо добавить строковый контрол Subject
типа Строка
для ввода темы документа. Он будет связан с колонкой AbDocuments: Subject
. В этот контрол может быть введён большой объём текста (тип колонки String(Max)
может быть больше 4000 символов), поэтому он должен растягиваться на ширину всех колонок (флаг Растянуть по ширине). Для удобства использования нужно указать минимальное и максимальное количество строк:
Минимум строк: 3
Максимум строк: 6
Следующим шагом будет указание обязательности для заполнения полей. Так, строка является заполненной, когда она содержит хотя бы один символ, отличный от пробелов, а любое другое значение заполнено, когда оно не пустое (например, когда ссылка задана). Пользователь будет видеть поле как обязательное, если поставить флаг Отметить как обязательное, однако эта настройка лишь добавляет звёздочку в конец названия контрола, и сотрудник всё равно может оставить его пустым, поэтому лучшим способом являются валидаторы.
Валидаторы для обязательных полей¶
Валидатор определяет, что конкретное поле карточки является обязательным (или подходит под другое условие, определяемое типом валидатора, например, числовое поле является положительным). Преимущество задания ограничений через валидаторы состоит в том, что все контролы, связанные с этим полем через свойство Card fields
, будут оповещать пользователя о необходимости заполнения этого поля. Кроме того, даже при отсутствии таких контролов проверка условий по полям с валидаторами всё равно будет выполняться при сохранении карточки. Таким образом, значение поля может вычисляться в расширениях и отображаться пользователю в другой форме, а проверка при сохранении будет выполняться именно для этого поля.
Создание валидатора выполняется через контекстное меню на узле Валидаторы, который вложен в узел с типом карточки.
Существует три типа валидаторов:
-
Непустая секция
определяет, что коллекционная или древовидная секция содержит хотя бы одно значение; -
Непустое поле
определяет, что выбранное поле (физическая или комплексная колонка) содержит непустое значение; -
Уникальное поле
определяет, что выбранное поле (физическая или комплексная колонка) содержит уникальное значение.
Например, нужно добавить валидатор типа Непустое поле
. После раскрытия узла Валидаторы можно увидеть добавленный валидатор и выбрать его. Для настройки данного валидатора нужно указать для него колонку AbDocuments.Subject
в свойстве Проверяемое поле
, чтобы этот валидатор проверял, что в теме документа присутствуют отличные от пробелов символы. В свойстве Сообщение об ошибке
задаётся сообщение, которое увидит пользователь, когда попытается сохранить карточку с незаполненным полем. Если сообщение не задать, то пользователь увидит системное сообщение, которое полезно для отладки, но для сотрудника будет неудобным.
Аналогично нужно добавить валидаторы на поля Number
и Type
, т.е. номер и тип документа будут обязательными для заполнения. Поле Partner
с контрагентом может быть не заполнено - для некоторых типов документов контрагент может не указываться.
Если открыть окно предпросмотра сейчас, то рядом с заголовками полей, с которыми связаны валидаторы, отобразится звёздочка. Она индицирует для пользователя тот факт, что поле нельзя оставлять пустым.
Создание экземпляра карточки¶
Теперь, наконец, настройка типа карточки завершена, и в системе есть всё необходимое, чтобы создать экземпляр карточки.
Для этого нужно открыть основное меню и выбрать пункт Создать карточку. Администратор увидит большой перечень карточек, которые можно создать, для пользователя перечень будет ограничен правилами доступа. Созданный тип карточки AbDocument
будет доступен всем сотрудникам.
Выбрав пункт Ab -> Document, карточка откроется в новой вкладке. Она создана только в памяти клиентского приложения, т.е. в БД нет записей, соответствующих карточке. Внешний вид карточки похож на отображение в окне предпросмотра в редакторе типов карточек.
Если карточку сразу же сохранить (пункт Сохранить новую основного меню, кнопка дискеты на тулбаре или Ctrl + S), то пользователю будет показано окно с ошибкой, где перечисляются сообщения всех сработавших валидаторов (текст сообщения задавался в свойстве валидатора Сообщение об ошибке).
Закрыв окно, пользователь увидит карточку, в которой незаполненные поля были подсвечены красным. Так валидаторы “сообщили” контролам, что поля не заполнены, и те показали рамки, которые исчезают после заполнения. Если заполнить все обязательные поля, карточка сохранится.
Заголовок вкладки с карточкой изменился с Новая карточка
на Карточка
, что показывает, что карточка сохранена. При сохранении карточка записывает свои данные в БД, а затем загружается из БД. При этом в БД была создана строка (запрос INSERT
) в таблице Instances
(системная таблица, описывающая системные свойства карточки), а также добавлена строка в строковую секцию AbDocuments
. Т.к. это единственная секция карточки, то других строк добавлено не было, но сложные карточки могут содержать десятки строковых и коллекционных секций. При последующих сохранениях карточки изменённые строки будут обновляться запросами UPDATE
.
Если в заголовке вкладки должно быть выведено другое название карточки, вычисляемое по полям этой карточки (например, из поля Number), то для этого необходимо заполнить поле Формат дайджеста, которое находится в настройках типа карточки. Подробнее о заполнении поля можно узнать в руководстве администратора.
Note
Также можно добавить в представление кнопку создания карточки. Делается это в области Рабочие места -> Documents -> Documents -> Свойства -> Расширения -> Добавить расширение -> CreateCardExtention. Чтобы кнопка работала, нужно нажать кнопку напротив добавленного расширения и указать алиас типа карточки.
Открытие карточки из представления¶
Если обновить представление Documents (пункт Обновить основного меню или F5), представление покажет одну строку с только что созданной карточкой.
Её можно открыть двойным кликом по строке представления.
Заголовок вкладки теперь 1
, т.е. значение поля Number. Это штатная возможность платформы, когда представление или контрол со ссылкой предоставляют текст с названием карточки.
Note
Название карточки из ссылки
Если взглянуть ещё раз на Reference
, ссылающийся на документ в метаинформации представления AbDocuments
:
{
"CardType": null,
"CardTypeColumn": null,
"ColPrefix": "Doc",
"Condition": null,
"DisplayValueColumn": "DocNumber",
"IsCard": true,
"OpenOnDoubleClick": true,
"RefSection": [
{
"::single_type": "str"
},
"AbDocuments"
]
},
Можно заметить, что была открыта карточка именно по этой ссылке Reference
, т.к. в ней указаны свойства "OpenOnDoubleClick": true
и "IsCard": true
. Идентификатор карточки был получен из колонки-идентификатора DocID
, т.к. в свойстве "ColPrefix": "Doc"
определяется, что в ссылку входят все колонки, алиас которых начинается с Doc
, и DocID
является первой подходящей колонкой с типом данных uniqueidentifier
(Guid
в схеме данных).
А заголовок вкладки с карточкой предоставила колонка "DisplayValueColumn": "DocNumber"
для строки, по которой дважды кликнули.
Сабсеты¶
Для объяснения работы сабсетов необходимо добавить несколько карточек в созданное представление:
Сабсеты определяют режим выборки представления, т.е. SQL-запрос представления выполняется либо для выборки данных, отображаемых в таблице (без сабсета), либо для определения общего количества строк при постраничном выводе (сабсет, указанный в RowCountSubset
), либо при группировке, вызванной на узле, чтобы отобразить значения как подузлы.
Для добавления сабсетов необходимо воспользоваться представлением Subsets (группировки), которое находится в метаданных.
Код, который необходимо заменить во вкладке "Редактор JSON":
{
"Alias": "AbDocuments",
"Appearance": null,
"Appearances": null,
"AutoSelectFirstRow": true,
"AutoWidthRowLimit": null,
"Caption": "Documents",
"CollapseGroups": false,
"Columns": [
{
"Alias": "DocID",
"Appearance": null,
"CalendarIDColumn": null,
"CalendarOverdueFormat": null,
"CalendarQuantsColumn": null,
"Caption": null,
"Condition": null,
"DisableGrouping": false,
"HasTag": false,
"Hidden": true,
"InvisibleByDefault": false,
"Localizable": false,
"MaxLength": null,
"PlannedColumn": null,
"SortBy": null,
"SortByFormat": null,
"TreatValueAsUtc": false,
"Type": "Guid Not Null"
},
{
"Alias": "DocNumber",
"Appearance": null,
"CalendarIDColumn": null,
"CalendarOverdueFormat": null,
"CalendarQuantsColumn": null,
"Caption": "Number",
"Condition": null,
"DisableGrouping": false,
"HasTag": false,
"Hidden": false,
"InvisibleByDefault": false,
"Localizable": false,
"MaxLength": null,
"PlannedColumn": null,
"SortBy": "t.Number",
"SortByFormat": null,
"TreatValueAsUtc": false,
"Type": "Int64 Not Null"
},
{
"Alias": "DocSubject",
"Appearance": null,
"CalendarIDColumn": null,
"CalendarOverdueFormat": null,
"CalendarQuantsColumn": null,
"Caption": "Subject",
"Condition": null,
"DisableGrouping": false,
"HasTag": false,
"Hidden": false,
"InvisibleByDefault": false,
"Localizable": false,
"MaxLength": null,
"PlannedColumn": null,
"SortBy": null,
"SortByFormat": null,
"TreatValueAsUtc": false,
"Type": "String(Max) Not Null"
},
{
"Alias": "TypeID",
"Appearance": null,
"CalendarIDColumn": null,
"CalendarOverdueFormat": null,
"CalendarQuantsColumn": null,
"Caption": null,
"Condition": null,
"DisableGrouping": false,
"HasTag": false,
"Hidden": true,
"InvisibleByDefault": false,
"Localizable": false,
"MaxLength": null,
"PlannedColumn": null,
"SortBy": null,
"SortByFormat": null,
"TreatValueAsUtc": false,
"Type": "Int16 Not Null"
},
{
"Alias": "TypeName",
"Appearance": null,
"CalendarIDColumn": null,
"CalendarOverdueFormat": null,
"CalendarQuantsColumn": null,
"Caption": "Type",
"Condition": null,
"DisableGrouping": false,
"HasTag": false,
"Hidden": false,
"InvisibleByDefault": false,
"Localizable": false,
"MaxLength": null,
"PlannedColumn": null,
"SortBy": "t.TypeName",
"SortByFormat": null,
"TreatValueAsUtc": false,
"Type": "String(Max) Not Null"
},
{
"Alias": "PartnerID",
"Appearance": null,
"CalendarIDColumn": null,
"CalendarOverdueFormat": null,
"CalendarQuantsColumn": null,
"Caption": null,
"Condition": null,
"DisableGrouping": false,
"HasTag": false,
"Hidden": true,
"InvisibleByDefault": false,
"Localizable": false,
"MaxLength": null,
"PlannedColumn": null,
"SortBy": null,
"SortByFormat": null,
"TreatValueAsUtc": false,
"Type": "Guid Null"
},
{
"Alias": "PartnerName",
"Appearance": null,
"CalendarIDColumn": null,
"CalendarOverdueFormat": null,
"CalendarQuantsColumn": null,
"Caption": "Partner",
"Condition": null,
"DisableGrouping": false,
"HasTag": false,
"Hidden": false,
"InvisibleByDefault": false,
"Localizable": false,
"MaxLength": null,
"PlannedColumn": null,
"SortBy": null,
"SortByFormat": null,
"TreatValueAsUtc": false,
"Type": "String(Max) Null"
}
],
"ConnectionAlias": null,
"DefaultSortColumns": [
{
"Alias": "DocNumber",
"SortDirection": "Descending"
}
],
"EnableAutoWidth": false,
"ExportDataPageLimit": null,
"Extensions": null,
"FormatVersion::int": 3,
"GroupingColumn": null,
"MultiSelect": false,
"Overrides": null,
"PageLimit": null,
"Paging": "Always",
"Parameters": [
{
"Alias": "Number",
"AllowedOperands": null,
"AutoCompleteInfo": null,
"AutoCompleteMapping": null,
"Caption": "Number",
"Condition": null,
"DateTimeType": null,
"DisallowedOperands": null,
"DropDownInfo": null,
"EmptyStringIsNotNull": false,
"Hidden": false,
"HideAutoCompleteButton": false,
"IgnoreCase": true,
"Multiple": true,
"RefSection": null,
"TreatValueAsUtc": false,
"Type": "Int64 Not Null"
},
{
"Alias": "Subject",
"AllowedOperands": null,
"AutoCompleteInfo": null,
"AutoCompleteMapping": null,
"Caption": "Subject",
"Condition": null,
"DateTimeType": null,
"DisallowedOperands": null,
"DropDownInfo": null,
"EmptyStringIsNotNull": false,
"Hidden": false,
"HideAutoCompleteButton": false,
"IgnoreCase": true,
"Multiple": true,
"RefSection": null,
"TreatValueAsUtc": false,
"Type": "String(Max) Not Null"
},
{
"Alias": "Type",
"AllowedOperands": null,
"AutoCompleteInfo": {
"ParamAlias": "Name",
"PopupColumns": [
{
"::single_type": "int"
},
1
],
"RefPrefix": "Type",
"ViewAlias": "AbDocumentTypes"
},
"AutoCompleteMapping": null,
"Caption": "Type",
"Condition": null,
"DateTimeType": null,
"DisallowedOperands": null,
"DropDownInfo": {
"PopupColumns": [
{
"::single_type": "int"
},
1
],
"RefPrefix": null,
"ViewAlias": "AbDocumentTypes"
},
"EmptyStringIsNotNull": false,
"Hidden": false,
"HideAutoCompleteButton": false,
"IgnoreCase": true,
"Multiple": true,
"RefSection": [
{
"::single_type": "str"
},
"AbDocumentTypes"
],
"TreatValueAsUtc": false,
"Type": "Int16 Not Null"
},
{
"Alias": "Partner",
"AllowedOperands": null,
"AutoCompleteInfo": {
"ParamAlias": "Name",
"PopupColumns": [
{
"::single_type": "int"
},
1
],
"RefPrefix": "Partner",
"ViewAlias": "Partners"
},
"AutoCompleteMapping": null,
"Caption": "Partner",
"Condition": null,
"DateTimeType": null,
"DisallowedOperands": null,
"DropDownInfo": null,
"EmptyStringIsNotNull": false,
"Hidden": false,
"HideAutoCompleteButton": false,
"IgnoreCase": true,
"Multiple": true,
"RefSection": [
{
"::single_type": "str"
},
"Partners"
],
"TreatValueAsUtc": false,
"Type": "Guid Null"
},
{
"Alias": "PartnerName",
"AllowedOperands": null,
"AutoCompleteInfo": null,
"AutoCompleteMapping": null,
"Caption": "Partner name",
"Condition": null,
"DateTimeType": null,
"DisallowedOperands": null,
"DropDownInfo": null,
"EmptyStringIsNotNull": false,
"Hidden": false,
"HideAutoCompleteButton": false,
"IgnoreCase": true,
"Multiple": true,
"RefSection": null,
"TreatValueAsUtc": false,
"Type": "String(255) Null"
}
],
"QuickSearchParam": null,
"References": [
{
"CardType": null,
"CardTypeColumn": null,
"ColPrefix": "Doc",
"Condition": null,
"DisplayValueColumn": "",
"IsCard": true,
"OpenOnDoubleClick": true,
"RefSection": [
{
"::single_type": "str"
},
"AbDocuments"
]
},
{
"CardType": null,
"CardTypeColumn": null,
"ColPrefix": "Type",
"Condition": null,
"DisplayValueColumn": "TypeName",
"IsCard": false,
"OpenOnDoubleClick": false,
"RefSection": [
{
"::single_type": "str"
},
"AbDocumentTypes"
]
},
{
"CardType": null,
"CardTypeColumn": null,
"ColPrefix": "Partner",
"Condition": null,
"DisplayValueColumn": "PartnerName",
"IsCard": true,
"OpenOnDoubleClick": false,
"RefSection": [
{
"::single_type": "str"
},
"Partners"
]
}
],
"RowCountSubset": "Count",
"RowCounterVisible": false,
"SelectionMode": "Row",
"Subsets": [
{
"Alias": "Types",
"Caption": "By type",
"CaptionColumn": "TypeName",
"Condition": null,
"CountColumn": null,
"HideZeroCount": false,
"Kind": "List",
"RefColumn": "TypeID",
"RefParam": "Type",
"TreeHasChildrenColumn": null,
"TreeRefParam": null
},
{
"Alias": "Count",
"Caption": null,
"CaptionColumn": null,
"Condition": null,
"CountColumn": null,
"HideZeroCount": false,
"Kind": "List",
"RefColumn": null,
"RefParam": null,
"TreeHasChildrenColumn": null,
"TreeRefParam": null
}
],
"TagsPosition": "None",
"TreatAsSingleQuery": false,
"TreeGroup": null,
"TreeGroupDisplayValue": null,
"TreeGroupId": null,
"TreeGroupParentId": null,
"TreeId": null,
"TreeParentId": null
}
Основные изменения в метаданных:
-
Теперь представление выполняется с пейджингом, который пользователь не может отключить
Paging: always
, т.к. большое количество документов, отображаемых на одной области, может нагрузить систему. Решением данной проблемы является разделение данных в представлении на страницы. -
Для пейджинга указывается название сабсета для подсчёта строк
RowCountSubset: Count
. Теперь в представлении заданSubset
с алиасомCount
, который выполняет представление как запрос SQL. Он был шаблонизирован особым образом и возвращает единственное значение – общее количество строк в представлении (т.е. сколько всего документов в системе). Это позволяет системе показать в панели пейджинга не только номер текущей страницы, но и общее количество страниц1 / 1
.Important
Если указан сабсет
RowCountSubset
, то он будет выполнен каждый раз при запросе данных представления системой. Если пользователь обновит представление или перейдёт на другую страницу, то сначала будет выполнен запрос для получения данных отображаемой страницы, а затем запрос на получение общего количества строк в представлении. Поэтому в целях оптимизации работы представления с большим количеством строк сабсетRowCountSubset
можно не указывать, тогда общее количество страниц не будет рассчитываться. Таким образом, например, оптимизировано представление История действий.
Сабсет по типу документа Types
будет выполнен с двумя значениями Incoming
и Outgoing
(т.к. ни одного документа с типом Internal
не создано). Эти значения после модификации SQL-запроса будут добавлены в узел с представлением.
Прежде чем подробнее описать сабсеты, необходимо модифицировать код запроса в поле Запрос.
select
#if(Normal) { /* (1) */
t.ID as DocID,
t.Number as DocNumber,
t.Subject as DocSubject,
t.TypeID,
t.TypeName,
t.PartnerID,
t.PartnerName
} { /* (2) */
t2.*
}
from
(
select
#if(Normal) { /* (3) */
t.ID,
row_number() over (order by #order_by) as rn
}
#if(Types) {
distinct t.TypeID, t.TypeName
}
#if(Count) { /* (4) */
count(*) as cnt
}
from AbDocuments t with(nolock)
where 1 = 1
#param(Number, t.Number)
#param(Subject, t.Subject)
#param(Type, t.TypeID)
#param(Partner, t.PartnerID)
#param(PartnerName, t.PartnerName)
) t2
#if(Normal) {
inner join AbDocuments t with(nolock) on t.ID = t2.ID
}
#if(PageOffset) { /* (5) */
where t2.rn >= #param(PageOffset) and t2.rn < (#param(PageOffset) + #param(PageLimit))
}
#if(Normal) {
order by t2.rn
}
#if(Types) {
order by t2.TypeName
}
-
Оператор
#if
добавляет своё содержимое в фигурных скобках{...}
, если выражение внутри круглых скобок#if(...)
выполняется. -
Вторые фигурные скобки (самый первый
#if
в запросе) аналогичны блоку “иначе”, т.е. они добавляются, если условие в круглых скобках не выполняется. -
#if(Normal)
выполняется (добавляет содержимое первых фигурных скобок), когда запрос выполняется в обычном режиме (без сабсетов). -
#if(<SubsetAlias>)
выполняется, если задан сабсет с указанным алиасом. Например,#if(Count)
выполняется, когда представление выполняется в режиме сабсетаCount
. -
#if(PageOffset)
выполняется, если задан специальный параметрPageOffset
с количеством строк, которые надо пропустить для определения первой отображаемой строки на текущей выводимой странице. Параметр задаётся системой, когда представление выполняется в режиме без сабсета#if(Normal)
и когда постраничное отображение включено:Paging: always
илиPaging: optional
(когда пользователь может сам переключить с постраничного отображения на полное). В общем случае#if(<ParamAlias>)
выполняется, если задан параметр с указанным алиасом (а алиасы параметров и сабсетов не могут совпадать). Например,#if(Number)
выполнится, если задано хотя бы одно значение для параметраNumber
с номером документа.
Выноски:
-
Оператор
#if
добавляет своё содержимое в фигурных скобках{...}
, если выражение внутри круглых скобок#if(...)
выполняется. -
Вторые фигурные скобки (самый первый
#if
в запросе) аналогичны блоку “иначе”, т.е. они добавляются, если условие в круглых скобках не выполняется. -
#if(Normal)
выполняется (добавляет содержимое первых фигурных скобок), когда запрос выполняется в обычном режиме (без сабсетов). -
#if(<SubsetAlias>)
выполняется, если задан сабсет с указанным алиасом. Например,#if(Count)
выполняется, когда представление выполняется в режиме сабсетаCount
. -
#if(PageOffset)
выполняется, если задан специальный параметрPageOffset
с количеством строк, которые надо пропустить для определения первой отображаемой строки на текущей выводимой странице. Параметр задаётся системой, когда представление выполняется в режиме без сабсета#if(Normal)
и когда постраничное отображение включено:Paging: always
илиPaging: optional
(когда пользователь может сам переключить с постраничного отображения на полное). В общем случае#if(<ParamAlias>)
выполняется, если задан параметр с указанным алиасом (а алиасы параметров и сабсетов не могут совпадать). Например,#if(Number)
выполнится, если задано хотя бы одно значение для параметраNumber
с номером документа.
Посмотреть, как выглядит запрос с нужным сабсетом, можно на вкладке Отладка в свойстве Выбранное подмножество.
Например, так выглядит запрос для сабсета Count
. Он возвращает общее количество строк в таблице с указанными параметрами фильтрации.
-- {"ViewAlias":"AbDocuments","Subset":"Count","IsAdministrator":true,"Parameters":["UserAccessLevel"]}
select
t2.*
from
(
select
count(*) as cnt
from AbDocuments t with(nolock)
where 1 = 1
) t2;
GO
В результате выводится количество:
Результаты выполнения для представления в режиме сабсета Types
выглядят так:
При выборе значения для представления AbDocuments
указывается параметр Type
, заданный в свойстве RefParam
сабсета. В параметр передаётся значение из колонки RefColumn: TypeID
из результатов выполнения представления в режиме сабсета Types
(а там возвращается две колонки: TypeID
с идентификатором и TypeName
с названием). Отображаемое пользователю значение (в дереве и при выборе в сообщении равен 'Outgoing'
) определяется по колонке CaptionColumn: TypeName
.
А при выполнении представления без сабсета получаем такой запрос:
-- {"ViewAlias":"AbDocuments","Subset":null,"IsAdministrator":true,"Parameters":["PageOffset","PageLimit","UserAccessLevel"],"OrderBy":{"DocNumber":"Descending"}}
select
t.ID as DocID,
t.Number as DocNumber,
t.Subject as DocSubject,
t.TypeID,
t.TypeName,
t.PartnerID,
t.PartnerName
from
(
select
t.ID,
row_number() over (order by [t].[Number] desc ) as rn
from AbDocuments t with(nolock)
where 1 = 1
) t2
inner join AbDocuments t with(nolock) on t.ID = t2.ID
where t2.rn >= 1 and t2.rn < (1 + 20)
order by t2.rn;
GO
В запрос система автоматически передаёт параметры пейджинга PageOffset
(номер записи, начиная с которой отображается текущая страница), PageLimit
(количество строк в одной странице), идентификатор текущего пользователя CurrentUser
, имя языка локализации для пользователя Locale
и настройки форматирования дат и чисел для текущего пользователя FormatSettings
. Параметр Number
передаётся, т.к. мы его указали (как если бы его указал пользователь).
Результат запроса выглядит так:
Настроенные сабсеты можно отобразить по умолчанию на рабочих местах сотрудников, это делается в области Рабочие места. Для удобства использования указываются настройки для сабсета по типу документа. Для этого нужно нажать кнопку сабсета в узле дерева и кликнуть на сабсет By type.
В области справа указываются свойства отображения узла с сабсетом в дереве.
-
Узел можно переименовать, указав ему другой Заголовок.
-
Узел можно скрыть
Режим отображения: Скрыть от пользователя
, т.е. для конкретного узла Documents в рабочем месте Documents сабсетBy type
будет недоступен. -
Узел можно добавлять сразу в раскрытом состоянии
Отображать узел: Развернутым
. Эта настройка полезна для удобства использования.
Так настройка Отображать узел: Развернутым
выглядит в действии. После добавления пользователем сабсета:
Он сразу добавляется в развёрнутом виде:
В то время, как без этой настройки узел сабсета свёрнут. Добавлять сабсет как свёрнутый узел полезно, если представление в режиме этого сабсета может выполняться длительное время, и пользователь может случайно кликнуть не по тому сабсету и попасть на экран загрузки. Если узел сабсета добавляется свёрнутым, то сабсет выполняется при первом раскрытии этого узла (или при обновлении представления, когда выбран узел сабсета или один из его подузлов).
История действий¶
История действий – это логи аудита, которые фиксируют каждое действие с карточкой. Они записываются системой для тех типов карточек, у которых в настройках включен флаг Фиксировать действия. История действий доступна администраторам системы и открывается в основном меню через открытую вкладку с нужной карточкой: Системные -> История действий.
В колонке Объект созданной карточки отображается <имя неизвестно>
, т.к. для неё не был определен формат дайджеста. Любую запись в истории можно открыть, и прочитать подробную информацию обо всём, происходящем с карточкой. Запись по созданию карточки выглядит следующим образом:
Здесь для строковой секции AbDocuments
записаны значения полей, которые заполнил пользователь.
Структура карточки¶
Структура карточки показывает в JSON-подобном формате сериализованные данные карточки, которые были отправлены на сервер. Такие данные называются структурой карточки. По этим данным также видно, какая информация указана в секции AbDocuments
. Просмотреть её до того, как карточка будет сохранена, можно, выбрав пункт Другие -> Структура карточки в основном меню.
Если в поле Partner
указать некоторого контрагента Syntellect
(если его нет, то можно создать карточку контрагента с таким именем), и, не сохраняя карточку, открыть её структуру, то она будет выглядеть следующим образом.
Здесь отображается не полная структура, а та, что будет направлена на сервер при сохранении, она содержит только системные поля и изменённые поля в секциях. В секции AbDocuments
ссылочный контрол заполнил два поля: ParnterID
с идентификатором контрагента и PartnerName
с его именем. В разделе выше, в котором описывалась работа представлений, было рассказано, как поля из представления Partners
заполняются в полях карточки.
Note
Отображение колонок представления на поля карточки
-
У полей комплексной колонки
Partner
отбрасывается префикс, т.е. вместоPartnerID
получаем суффиксID
, а вместоPartnerName
–Name
. -
В представлении
Partners
выполняется поиск подходящей ссылкиReference
, из которой также удаляется префикс, заданный вColPrefix
. Это оставляет те же суффиксыID
иName
. -
Для колонок с одинаковыми суффиксами переносятся данные, т.е. из
ID
запроса (PartnerID
) вID
колонки (тожеPartnerID
, т.к. префиксы совпали).
Чтобы посмотреть все поля в структуре карточки (которые визуализируются контролами), нужно снять флаг Карточка перед сохранением.
Удаление карточки и её восстановление¶
Поскольку в типе карточки был поставлен флаг Удалять в корзину, то карточка удаляется в корзину, из которой она может быть восстановлена администратором. Однако при удалении карточки все строки из её секций фактически удаляются, а в корзине размещается сериализованная структура карточки. Поэтому из таблицы AbDocuments
(и из одноимённого представления) строка с карточкой будет удалена.
Удалить карточку можно через основное меню (Другие -> Удалить). История действий по карточке с отметкой удаления будет доступна не из карточки (которая удалена), а в рабочем месте Администратор из представления Служебные -> История действий.
Сама удалённая карточка есть в представлении Администратор -> Служебные -> Удаленные карточки.
Открыв удалённую карточку по двойному клику, можно будет выполнить следующие действия: Просмотр, Восстановить, Исправить или окончательно Удалить (кнопки тулбара). Для удалённой карточки используется имя <имя неизвестно>
, т.к. для неё не настроен дайджест.
Система автоматически удаляет карточки спустя несколько дней после их удаления (по умолчанию через 30 дней), для определения нужного времени необходимо настроить RemoveDeletedCardsPlugin
.