Merge pull request #10 from TouchInstinct/table_of_contents
Table of contents + Comments
This commit is contained in:
commit
2158dcc70e
|
|
@ -1,23 +0,0 @@
|
|||
import LeadKit
|
||||
import ObjectMapper
|
||||
|
||||
final class ApiDateFormattingService: DateFormattingService {
|
||||
|
||||
static let shared = ApiDateFormattingService()
|
||||
|
||||
private init() {
|
||||
super.init(formattingArguments: [
|
||||
{% for dateFormat in dateFormats -%}
|
||||
DateFormattingArguments(dateFormat: "{{ dateFormat }}"){% if not (loop.last) %},{%- endif %}
|
||||
{% endfor %}
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension ApiDateFormattingService {
|
||||
|
||||
func mappingTransform(for dateFormat: String) -> TransformOf<Date, String> {
|
||||
return mappingTransform(for: DateFormattingArguments(dateFormat: dateFormat))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ import java.io.IOException;
|
|||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
|
@ -93,4 +94,4 @@ public class {% include 'blocks/class/classtype.twig' with { type: type } %} ext
|
|||
{%- include 'blocks/class/fields-read-object.twig' with { fields: fields } %}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,15 +6,13 @@
|
|||
* {{ field.description }}
|
||||
*/
|
||||
{{ utils.writeNullCheckAnnotation(field.type.type.baseTypeName, field.nullable, field.optional) }}
|
||||
//TODO: getter with is****
|
||||
public {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} get{{ utils.capitalize(field.name) }}() {
|
||||
public {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} {% if (field.type.type.baseTypeName == "Bool") and (field.name matches "^is[A-Z,0-9].*") -%}{{ field.name }}{%- else -%}get{{ utils.capitalize(field.name) }}{%- endif -%}() {
|
||||
{{ utils.formatValueGetter(field.name, field.type.type, field.nullable, field.optional) }}
|
||||
}
|
||||
|
||||
/**
|
||||
* {{ field.description }}
|
||||
*/
|
||||
//TODO: setter with is****
|
||||
public void set{{ utils.capitalize(field.name) }}({{ utils.writeNullCheckAnnotation(field.type.type.baseTypeName, field.nullable, field.optional) }} final {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} {{ field.name }}) {
|
||||
{{ utils.formatValueSetter("this", field.name, field.type.type.baseTypeName, fiel.nullable, field.optional ) }}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
{%- import '../../utils.twig' as utils -%}
|
||||
{% for field in fields -%}
|
||||
{%- if field.optional -%}
|
||||
{{ utils.formatValidateObject(concat("this.", field.name, ".get()"), field.type.type, field.nullable) }}
|
||||
{{ utils.formatValidateObject(concat("this.", field.name, ".get()"), field.type, field.type.type, field.nullable) }}
|
||||
{%- else -%}
|
||||
{{ utils.formatValidateObject(concat("this.", field.name), field.type.type, field.nullable) }}
|
||||
{{ utils.formatValidateObject(concat("this.", field.name), field.type, field.type.type, field.nullable) }}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
|
|
@ -201,7 +201,7 @@ inputStream.readBoolean()
|
|||
{%- endif -%}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro formatValidateObject(object, valueType, nullable) %}
|
||||
{% macro formatValidateObject(object, valueTopType, valueType, nullable) %}
|
||||
{% import _self as self %}
|
||||
{%- if not nullable and valueType.baseTypeName != "Int" and valueType.baseTypeName != "Long" and valueType.baseTypeName != "Double" and valueType.baseTypeName != "Bool" %}
|
||||
validateNotNull({{ object }});
|
||||
|
|
@ -213,7 +213,7 @@ inputStream.readBoolean()
|
|||
}
|
||||
{%- else -%}
|
||||
validateCollection({{ object }}.values(), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- elseif valueType.baseTypeName == "Array" %}
|
||||
{%- if nullable -%}
|
||||
if ({{ object }} != null) {
|
||||
|
|
@ -222,9 +222,28 @@ inputStream.readBoolean()
|
|||
{%- else -%}
|
||||
validateCollection({{ object }}, CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
|
||||
{%- endif -%}
|
||||
{%- elseif valueType.baseTypeName != "Int" and valueType.baseTypeName != "Long" and valueType.baseTypeName != "Double" and valueType.baseTypeName != "Bool" and valueType.baseTypeName != "String" and valueType.baseTypeName != "Decimal" and valueType.baseTypeName != "DateTime" %}
|
||||
{%- elseif valueType.baseTypeName != "Int"
|
||||
and valueType.baseTypeName != "Long"
|
||||
and valueType.baseTypeName != "Double"
|
||||
and valueType.baseTypeName != "Bool"
|
||||
and valueType.baseTypeName != "String"
|
||||
and valueType.baseTypeName != "Decimal"
|
||||
and valueType.baseTypeName != "DateTime"
|
||||
and (valueTopType.values is empty) %}
|
||||
{%- if valueTopType.allFieldsOrdered is empty %}
|
||||
if ({{ object }} instanceof ApiModel) {
|
||||
((ApiModel) {{ object }}).validate();
|
||||
} else if ({{ object }} instanceof List) {
|
||||
validateCollection(((List) {{ object }}), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
|
||||
} else if ({{ object }} instanceof Map) {
|
||||
validateCollection(((Map) {{ object }}).values(), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
|
||||
}
|
||||
{%- elseif nullable %}
|
||||
if ({{ object }} != null) {
|
||||
{{ object }}.validate();
|
||||
}
|
||||
{%- else -%}
|
||||
{{ object }}.validate();
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{% endmacro %}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import ObjectMapper
|
||||
|
||||
{%- include 'blocks/class/date-transformers.twig' with { fields: fields } %}
|
||||
{%- include 'blocks/class/date-transformers.twig' with { fields: fields, classType: classType } %}
|
||||
|
||||
/// {{ description }}
|
||||
{% if (not hasChilds) -%}final {% endif %}class {{ classType }}: {{ parentClassType }} {
|
||||
|
|
@ -23,20 +23,27 @@ import ObjectMapper
|
|||
}
|
||||
|
||||
required init(map: Map) throws {
|
||||
{%- include 'blocks/class/fields-mapping-from-map.twig' with { fields: fields } -%}
|
||||
{%- include 'blocks/class/fields-mapping-from-map.twig' with {
|
||||
fields: fields,
|
||||
classType: classType
|
||||
} -%}
|
||||
{% if hasParent %}
|
||||
try super.init(map: map)
|
||||
{%- endif %}
|
||||
}
|
||||
|
||||
{% if hasParent %} override {% endif %}func mapping(map: Map) {
|
||||
{%- include 'blocks/class/fields-mapping-to-map.twig' with { fields: fields } -%}
|
||||
{%- include 'blocks/class/fields-mapping-to-map.twig' with {
|
||||
fields: fields,
|
||||
classType: classType
|
||||
} -%}
|
||||
{% if hasParent %}
|
||||
super.mapping(map: map)
|
||||
{%- endif %}
|
||||
}
|
||||
|
||||
}
|
||||
{#
|
||||
{% if not hasChilds %}
|
||||
extension {{ type.baseTypeName }}: Equatable {
|
||||
|
||||
|
|
@ -46,4 +53,5 @@ extension {{ type.baseTypeName }}: Equatable {
|
|||
}
|
||||
|
||||
}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
#}
|
||||
|
|
@ -8,7 +8,7 @@ import Foundation
|
|||
{% for value in values -%}
|
||||
/// - {{ utils.decapitalize(value.name) }}: {{ value.description }}
|
||||
{% endfor -%}
|
||||
enum {{ name }}: {{ enumutils.enumType(valuesTypes) }} {
|
||||
enum {{ name }}: {{ enumutils.enumType(valuesTypes) }}, RawRepresentable {
|
||||
{% include 'blocks/enum/cases.twig' with { values: values } %}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ class {{ serviceName }}: ApiNetworkService {
|
|||
return "{{ apiUrl }}"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
{%- for field in fields -%}
|
||||
{% if field.type.type.baseTypeName == "DateTime" -%}
|
||||
private let {{ field.name }}Transform = ApiDateFormattingService.shared.mappingTransform(for: "{{ field.type.dateFormat }}")
|
||||
private let {{ utils.dateTransformName(field.name, classType) }} = ApiDateFormattingService.shared.mappingTransform(for: "{{ field.type.dateFormat }}")
|
||||
{% endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
{%- import '../../macroses/common.utils.twig' as utils -%}
|
||||
{%- for field in fields %}
|
||||
{{ field.name }} = {{ utils.formatNullableOrOptional('try', field.nullable, field.optional) }} {{ utils.mappingFromMapForField(field) }}
|
||||
{{ field.name }} = {{ utils.formatNullableOrOptional('try', field.nullable, field.optional) }} {{ utils.mappingFromMapForField(field, classType) }}
|
||||
{%- endfor -%}
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
{%- for field in fields %}
|
||||
{%- if field.optional %}
|
||||
if {{ field.name }} != nil {
|
||||
{{ field.name }} >>> {{ utils.mappingToMapForField(field) }}
|
||||
{{ field.name }} >>> {{ utils.mappingToMapForField(field, classType) }}
|
||||
}
|
||||
{%- else %}
|
||||
{{ field.name }} >>> {{ utils.mappingToMapForField(field) }}
|
||||
{{ field.name }} >>> {{ utils.mappingToMapForField(field, classType) }}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
|
|
@ -2,19 +2,27 @@
|
|||
{{- concat(slice(text, 0, 1) | lower, slice(text, 1, text | length)) -}}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro capitalize(text) %}
|
||||
{{- concat(slice(text, 0, 1) | upper, slice(text, 1, text | length)) -}}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro formatNullableOrOptional(expr, nullable, optional) %}
|
||||
{{- expr -}}{%- if nullable or optional -%}?{%- endif -%}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro formatValueType(valueType) %}
|
||||
{%- import _self as self -%}
|
||||
|
||||
{%- if valueType.baseTypeName == "Array" -%}
|
||||
[{{ valueType.itemsType.baseTypeName }}]
|
||||
[{{ self.formatValueType(valueType.itemsType) }}]
|
||||
{%- elseif valueType.baseTypeName == "Map" -%}
|
||||
[{{ valueType.keysType.baseTypeName }}: {{ valueType.valuesType.baseTypeName }}]
|
||||
[{{ self.formatValueType(valueType.keysType) }}: {{ self.formatValueType(valueType.valuesType) }}]
|
||||
{%- elseif valueType.baseTypeName == "DateTime" -%}
|
||||
Date
|
||||
{%- elseif valueType.baseTypeName == "Long" -%}
|
||||
Int64
|
||||
{%- elseif valueType.baseTypeName == "Decimal" -%}
|
||||
NSDecimalNumber
|
||||
{%- else -%}
|
||||
{{ valueType.baseTypeName }}
|
||||
{%- endif -%}
|
||||
|
|
@ -28,18 +36,30 @@
|
|||
{%- endif -%}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro mappingFromMapForField(field) %}
|
||||
{% macro mappingFromMapForField(field, className) %}
|
||||
{%- import _self as self -%}
|
||||
|
||||
{%- if field.type.type.baseTypeName == "DateTime" -%}
|
||||
map.value("{{ field.jsonName }}", using: {{ field.name -}}Transform)
|
||||
map.value("{{ field.jsonName }}", using: {{ self.dateTransformName(field.name, className) -}})
|
||||
{%- elseif field.type.type.baseTypeName == "Decimal" -%}
|
||||
map.value("{{ field.jsonName }}", using: NSDecimalNumberTransform())
|
||||
{%- else -%}
|
||||
map.value("{{ field.jsonName }}")
|
||||
{%- endif -%}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro mappingToMapForField(field) %}
|
||||
{% macro mappingToMapForField(field, className) %}
|
||||
{%- import _self as self -%}
|
||||
|
||||
{%- if field.type.type.baseTypeName == "DateTime" -%}
|
||||
(map["{{ field.jsonName }}"], {{ field.name -}}Transform)
|
||||
(map["{{ field.jsonName }}"], {{ self.dateTransformName(field.name, className) -}})
|
||||
{%- else -%}
|
||||
map["{{ field.jsonName }}"]
|
||||
{%- endif -%}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro dateTransformName(fieldName, className) %}
|
||||
{%- import _self as self -%}
|
||||
|
||||
{{ self.decapitalize(className) }}{{ self.capitalize(fieldName) -}}Transform
|
||||
{%- endmacro %}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
{%- include 'blocks/head.html.twig' with { title: pageTitle, cssFolderPath: cssFolderPath } %}
|
||||
|
||||
<body class="main-page">
|
||||
<div class="aside aside-left">
|
||||
<div class="header">
|
||||
<div class="title">{{ pageTitle }}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="aside aside-right">
|
||||
{%- include 'blocks/header.html.twig' with {
|
||||
imagesFolderPath: imagesFolderPath,
|
||||
methodsPath: methodsPath,
|
||||
relativeToRootPath: relativeToRootPath
|
||||
} %}
|
||||
|
||||
<div class="content">
|
||||
<h1>
|
||||
Оглавление
|
||||
</h1>
|
||||
<div class="page-data">
|
||||
{%- include 'blocks/table-of-contents-body.html.twig' with {
|
||||
methods: tableOfContents.methods,
|
||||
classes: tableOfContents.classes,
|
||||
enums: tableOfContents.enums
|
||||
} %}
|
||||
</div>
|
||||
|
||||
{% if methods is not null %}
|
||||
<h1>
|
||||
Методы
|
||||
</h1>
|
||||
{% for method in methods %}
|
||||
<div class="page-data">
|
||||
{%- include 'blocks/method-body.html.twig' with {
|
||||
method: method,
|
||||
objectsLinks: objectsLinks,
|
||||
showSandbox: false
|
||||
} %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if classes is not null %}
|
||||
<h1>
|
||||
Классы
|
||||
</h1>
|
||||
{% for class in classes %}
|
||||
<div class="page-data">
|
||||
{%- include 'blocks/class-body.html.twig' with {
|
||||
structure: class,
|
||||
objectsLinks: objectsLinks
|
||||
} %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if enums is not null %}
|
||||
<h1>
|
||||
Перечисления
|
||||
</h1>
|
||||
{% for enum in enums %}
|
||||
<div class="page-data">
|
||||
{%- include 'blocks/enum-body.html.twig' with {
|
||||
structure: enum,
|
||||
objectsLinks: objectsLinks
|
||||
} %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{%- include 'blocks/scripts.html.twig' with { jsFolderPath: jsFolderPath } %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<h2>Описание</h2>
|
||||
<p class="sub-header">{{ structure.type.baseTypeName }} - {{ structure.description }}</p>
|
||||
|
||||
{%- include 'comment.html.twig' with { comment: structure.comment } %}
|
||||
|
||||
<h2>Структура данных</h2>
|
||||
<div class="table">
|
||||
<div class="part-table">
|
||||
<div class="row-header">
|
||||
<div>Название поля</div>
|
||||
<div>Тип поля</div>
|
||||
<div class="text-centered">Описание</div>
|
||||
<div>Обязательность</div>
|
||||
</div>
|
||||
{% for field in structure.allFieldsOrdered -%}
|
||||
{%- include 'field-row.html.twig' with {
|
||||
field: field,
|
||||
objectsLinks: objectsLinks
|
||||
} %}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{%- if comment is not null -%}
|
||||
<h2>Комментарий</h2>
|
||||
<p class="sub-header">{{ comment }}</p>
|
||||
{%- endif -%}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<h2>Описание</h2>
|
||||
<p class="sub-header">{{ structure.name }} - {{ structure.description }}</p>
|
||||
|
||||
{%- include 'comment.html.twig' with { comment: structure.comment } %}
|
||||
|
||||
<h2>Возможные значения</h2>
|
||||
<div class="table table--small">
|
||||
<div class="part-table">
|
||||
<div class="row-header">
|
||||
<div>Значения</div>
|
||||
<div>Описание</div>
|
||||
</div>
|
||||
{% for value in structure.values %}
|
||||
<div class="row-body">
|
||||
<div>{{ value.value }}</div>
|
||||
<div>{{ value.description }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -3,9 +3,16 @@
|
|||
{%- import '../utils.twig' as utils -%}
|
||||
|
||||
{%- if valueType.baseTypeName == "Map" -%}
|
||||
Map<{{- self.formatValueType(valueType.keysType, false, objectsLinks) -}}, {{- self.formatValueType(valueType.valuesType, false, objectsLinks) -}}>
|
||||
{%- set keysType = self.formatValueType(valueType.keysType, false, objectsLinks) -%}
|
||||
{%- set valuesType = self.formatValueType(valueType.valuesType, false, objectsLinks) -%}
|
||||
{%- set mapType = concat("Map<", keysType, ", ", valuesType, ">") -%}
|
||||
|
||||
{{- utils.formatNullable(mapType, nullable) -}}
|
||||
{%- elseif valueType.baseTypeName == "Array" -%}
|
||||
{{- self.formatValueType(valueType.itemsType, false, objectsLinks) -}}[]
|
||||
{%- set itemsType = self.formatValueType(valueType.itemsType, false, objectsLinks) -%}
|
||||
{%- set arrayType = concat(itemsType, "[]") -%}
|
||||
|
||||
{{- utils.formatNullable(arrayType, nullable) -}}
|
||||
{%- else -%}
|
||||
{%- set link = null -%}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<div class="header">
|
||||
<div class="search-block">
|
||||
<i class="icon-search"></i>
|
||||
<input type="text" placeholder="Поиск" data-methods-path="{{ methodsPath }}" data-relative-to-root-path="{{ relativeToRootPath }}">
|
||||
<input type="text" placeholder="Поиск" data-relative-to-root-path="{{ relativeToRootPath }}">
|
||||
<div class="typeahead-container typeahead-container--hide"><div class="typeahead-content"></div></div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,35 @@
|
|||
<menu class="main">
|
||||
<li {%- if mainMenu.indexMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.indexMenuItem.path }}">Общие принципы построения API</a></li>
|
||||
<li {%- if mainMenu.methodsMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.methodsMenuItem.path }}">Методы</a></li>
|
||||
<li {%- if mainMenu.notificationsMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.notificationsMenuItem.path }}">PUSH-нотификации</a></li>
|
||||
<li {%- if mainMenu.structuresMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.structuresMenuItem.path }}">Структуры данных</a></li>
|
||||
<li {%- if mainMenu.versioningMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.versioningMenuItem.path }}">Версионирование API</a></li>
|
||||
<li {%- if mainMenu.errorsMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.errorsMenuItem.path }}">Список возможных ошибок</a></li>
|
||||
|
||||
{%- if mainMenu.indexMenuItem is not null %}
|
||||
<li {%- if mainMenu.indexMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.indexMenuItem.path }}">Общие принципы построения API</a></li>
|
||||
{% endif %}
|
||||
|
||||
{%- if mainMenu.methodsMenuItem is not null %}
|
||||
<li {%- if mainMenu.methodsMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.methodsMenuItem.path }}">Методы</a></li>
|
||||
{% endif %}
|
||||
|
||||
{%- if mainMenu.notificationsMenuItem is not null %}
|
||||
<li {%- if mainMenu.notificationsMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.notificationsMenuItem.path }}">PUSH-нотификации</a></li>
|
||||
{% endif %}
|
||||
|
||||
{%- if mainMenu.structuresMenuItem is not null %}
|
||||
<li {%- if mainMenu.structuresMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.structuresMenuItem.path }}">Структуры данных</a></li>
|
||||
{% endif %}
|
||||
|
||||
{%- if mainMenu.versioningMenuItem is not null %}
|
||||
<li {%- if mainMenu.versioningMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.versioningMenuItem.path }}">Версионирование API</a></li>
|
||||
{% endif %}
|
||||
|
||||
{%- if mainMenu.errorsMenuItem is not null %}
|
||||
<li {%- if mainMenu.errorsMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.errorsMenuItem.path }}">Список возможных ошибок</a></li>
|
||||
{% endif %}
|
||||
|
||||
{%- if mainMenu.tableOfContents is not null %}
|
||||
<li {%- if mainMenu.tableOfContents.active %} class="active" {%- endif -%}><a href="{{ mainMenu.tableOfContents.path }}">Оглавление</a></li>
|
||||
{% endif %}
|
||||
|
||||
{%- if mainMenu.allContents is not null %}
|
||||
<li {%- if mainMenu.allContents.active %} class="active" {%- endif -%}><a href="{{ mainMenu.allContents.path }}">Версия для печати</a></li>
|
||||
{% endif %}
|
||||
|
||||
</menu>
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<h2>Метод</h2>
|
||||
<p class="sub-header">POST {{ method.url }}</p>
|
||||
|
||||
<h2>Описание</h2>
|
||||
<p class="sub-header">{{ method.description }}</p>
|
||||
|
||||
{%- include 'comment.html.twig' with { comment: method.comment } %}
|
||||
|
||||
<h2>Параметры</h2>
|
||||
{% if method.requestFields is not empty %}
|
||||
<div class="table example-response-expanded">
|
||||
<div class="part-table">
|
||||
<div class="row-header">
|
||||
<div>Название параметра</div>
|
||||
<div>Тип параметра</div>
|
||||
<div class="text-centered">Описание</div>
|
||||
<div>Обязательность</div>
|
||||
</div>
|
||||
{% for field in method.requestFields -%}
|
||||
{%- include 'field-row.html.twig' with {
|
||||
field: field,
|
||||
objectsLinks: objectsLinks
|
||||
} %}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
{% if default(showSandbox, true) %}
|
||||
<div class="part-block">
|
||||
<a class="show-example-response">Пример запроса</a>
|
||||
</div>
|
||||
<div class="part-example-response">
|
||||
<div class="inputs">
|
||||
{% for field in method.requestFields -%}
|
||||
<label>
|
||||
{{ field.jsonName }}<br>
|
||||
{% if field.type.values is not empty -%}
|
||||
<div class="styled-select">
|
||||
<select data-name="{{ field.jsonName }}">
|
||||
{% for value in field.type.values %}
|
||||
<option>{{ value.value }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{%- if field.optional or field.nullable -%}
|
||||
{% include 'sandbox-optional-nullable.html.twig' with { field: field } %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{%- else %}
|
||||
{%- if field.optional or field.nullable -%}
|
||||
<div class="styled-input">
|
||||
<input type="text" data-name="{{ field.jsonName }}">
|
||||
{% include 'sandbox-optional-nullable.html.twig' with { field: field } %}
|
||||
</div>
|
||||
{%- else %}
|
||||
<input type="text" data-name="{{ field.jsonName }}">
|
||||
{% endif %}
|
||||
{%- endif %}
|
||||
</label>
|
||||
{% endfor %}
|
||||
|
||||
<button class="btn run-btn" data-server-method-path="{{ serverMethodPath }}">
|
||||
Выполнить
|
||||
</button>
|
||||
</div>
|
||||
<div class="text-response"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="sub-header">Параметры отсутствуют</p>
|
||||
{% endif %}
|
||||
|
||||
<h2>Возможные ошибки</h2>
|
||||
{% for value in method.errorsEnumeration.values -%}
|
||||
{%- if value.value in method.errorsEnumeration.allowedValues %}
|
||||
<p class="sub-header">#Код {{ value.value }} — {{ value.description }}</p>
|
||||
{%- endif -%}
|
||||
{%- endfor %}
|
||||
|
||||
<h2>Результат</h2>
|
||||
<p>Объект следующей структуры:</p>
|
||||
|
||||
<div class="table example-response-expanded">
|
||||
<div class="part-table">
|
||||
<div class="row-header">
|
||||
<div>Название поля</div>
|
||||
<div>Тип поля</div>
|
||||
<div class="text-centered">Описание</div>
|
||||
<div>Обязательность</div>
|
||||
</div>
|
||||
{% for field in method.responseFields -%}
|
||||
{%- include 'field-row.html.twig' with {
|
||||
field: field,
|
||||
objectsLinks: objectsLinks
|
||||
} %}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{%- if field.optional -%}
|
||||
<div class="clear-btn">×</div>
|
||||
{%- endif -%}
|
||||
{% if field.nullable -%}
|
||||
<div class="null-btn">NULL</div>
|
||||
{%- endif -%}
|
||||
|
|
@ -1,2 +1,4 @@
|
|||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="{{ jsFolderPath }}/main.js?v=1.02"></script>
|
||||
<script src="https://unpkg.com/split.js/split.min.js"></script>
|
||||
<script type="text/javascript" src="{{ jsFolderPath }}/main.js?v=1.02"></script>
|
||||
<script type="text/javascript" src="{{ jsFolderPath }}/searchItems.js?v=1.00"></script>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
{%- if methods is not null %}
|
||||
<h2>
|
||||
<a href="{{ methods.path }}">Методы</a>
|
||||
</h2>
|
||||
{% for methodsGroup in methods.items %}
|
||||
<h3>
|
||||
<a href="{{ methodsGroup.path }}">{{ methodsGroup.title }}</a>
|
||||
</h3>
|
||||
{% for method in methodsGroup.items -%}
|
||||
<li><a href="{{ method.path }}">{{ method.title }}</a></li>
|
||||
{% endfor -%}
|
||||
{% endfor %}
|
||||
|
||||
{%- endif %}
|
||||
|
||||
{%- if classes is not null %}
|
||||
<h2>
|
||||
<a href="{{ classes.path }}">Классы</a>
|
||||
</h2>
|
||||
{% for class in classes.items -%}
|
||||
<li><a href="{{ class.path }}">{{ class.title }}</a></li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{%- if enums is not null %}
|
||||
<h2>
|
||||
<a href="{{ enums.path }}">Перечисления</a>
|
||||
</h2>
|
||||
{% for enum in enums.items -%}
|
||||
<li><a href="{{ enum.path }}">{{ enum.title }}</a></li>
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
@font-face {
|
||||
font-family: SanFrancisco;
|
||||
font-family: Roboto;
|
||||
font-weight: 400;
|
||||
src: url(../fonts/SanFranciscoDisplay-Regular.otf);
|
||||
src: url(../fonts/Roboto-Regular.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: SanFrancisco;
|
||||
font-family: Roboto;
|
||||
font-weight: 500;
|
||||
src: url(../fonts/SanFranciscoDisplay-Medium.otf);
|
||||
src: url(../fonts/Roboto-Medium.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: SanFrancisco;
|
||||
font-family: Roboto;
|
||||
font-weight: 600;
|
||||
src: url(../fonts/SanFranciscoDisplay-Semibold.otf);
|
||||
src: url(../fonts/Roboto-Bold.ttf);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
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.
|
After Width: | Height: | Size: 91 B |
|
|
@ -1,5 +1,50 @@
|
|||
$(function () {
|
||||
$(document).ready(function () {
|
||||
let sizes = [30, 70];
|
||||
|
||||
const splitSizesKey = 'split-sizes';
|
||||
|
||||
try {
|
||||
const localStorageSizes = localStorage.getItem(splitSizesKey);
|
||||
sizes = JSON.parse(localStorageSizes);
|
||||
} catch (e) {
|
||||
console.info("Unable to read split size from localStorage. Using defaults.");
|
||||
}
|
||||
|
||||
let split = window.Split(['.aside-left', '.aside-right'], {
|
||||
sizes: sizes,
|
||||
minSize: [200, 769],
|
||||
onDragEnd: function () {
|
||||
try {
|
||||
sizes = split.getSizes();
|
||||
localStorage.setItem(splitSizesKey, JSON.stringify(sizes));
|
||||
} catch (e) {
|
||||
// SecurityError (DOM Exception 18): The operation is insecure.
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.split1 = split;
|
||||
|
||||
const beforePrint = function() {
|
||||
split.collapse(0);
|
||||
console.log('Functionality to run before printing.');
|
||||
};
|
||||
const afterPrint = function() {
|
||||
split.setSizes(sizes);
|
||||
console.log('Functionality to run after printing.');
|
||||
};
|
||||
|
||||
if (window.matchMedia) {
|
||||
const mediaQueryList = window.matchMedia('print');
|
||||
mediaQueryList.addListener(function(mql) {
|
||||
if (mql.matches) {
|
||||
beforePrint();
|
||||
} else {
|
||||
afterPrint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('.part-example-response .text-response').css('height', $('.inputs').height() - 21);
|
||||
|
||||
|
|
@ -67,39 +112,25 @@ $(function () {
|
|||
|
||||
$(document).on('keyup', '.search-block input', function (e) {
|
||||
var $searchInput = $(this);
|
||||
var methodsUrl = $searchInput.data('methodsPath');
|
||||
var relativeUrl = $searchInput.data('relativeToRootPath');
|
||||
var $typeaheadContainer = $searchInput.closest('.search-block').find('.typeahead-container');
|
||||
var $typeaheadContent = $typeaheadContainer.find('.typeahead-content');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
url: methodsUrl
|
||||
var itemsLink = '';
|
||||
searchItems
|
||||
.filter(function (item) {
|
||||
return item.name.toLowerCase().indexOf($searchInput.val().toLowerCase()) >= 0;
|
||||
})
|
||||
.done(
|
||||
function (response) {
|
||||
var itemsLink = '';
|
||||
response
|
||||
.filter(function (item) {
|
||||
return item.name.toLowerCase().indexOf($searchInput.val().toLowerCase()) >= 0;
|
||||
})
|
||||
.forEach(function (item) {
|
||||
itemsLink += '<a href="' + (relativeUrl ? relativeUrl + "/" : "") + item.url + '">' + item.name + '</a>'
|
||||
});
|
||||
$typeaheadContent.html(itemsLink);
|
||||
.forEach(function (item) {
|
||||
itemsLink += '<a href="' + (relativeUrl ? relativeUrl + "/" : "") + item.url + '">' + item.name + '</a>'
|
||||
});
|
||||
$typeaheadContent.html(itemsLink);
|
||||
|
||||
if (itemsLink != '') {
|
||||
$typeaheadContainer.removeClass('typeahead-container--hide');
|
||||
} else {
|
||||
$typeaheadContainer.addClass('typeahead-container--hide');
|
||||
}
|
||||
})
|
||||
.fail(
|
||||
function () {
|
||||
alert('Ошибка запроса.');
|
||||
});
|
||||
if (itemsLink != '') {
|
||||
$typeaheadContainer.removeClass('typeahead-container--hide');
|
||||
} else {
|
||||
$typeaheadContainer.addClass('typeahead-container--hide');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@
|
|||
|
||||
<menu class="secondary">
|
||||
{% for menu in menus %}
|
||||
{% include 'blocks/secondary-menu.html.twig' with {
|
||||
menu: menu,
|
||||
menuTitle: menu.title,
|
||||
activeItemTypeName: name
|
||||
} %}
|
||||
{% include 'blocks/secondary-menu.html.twig' with {
|
||||
menu: menu,
|
||||
menuTitle: menu.title,
|
||||
activeItemTypeName: name
|
||||
} %}
|
||||
{% endfor %}
|
||||
</menu>
|
||||
|
||||
|
|
@ -30,96 +30,10 @@
|
|||
|
||||
<div class="content">
|
||||
<div class="page-data">
|
||||
<h2>Метод</h2>
|
||||
<p class="sub-header">POST {{ url }}</p>
|
||||
|
||||
<h2>Параметры</h2>
|
||||
<div class="table example-response-expanded">
|
||||
<div class="part-table">
|
||||
<div class="row-header">
|
||||
<div>Название параметра</div>
|
||||
<div>Тип параметра</div>
|
||||
<div class="text-centered">Описание</div>
|
||||
<div>Обязательность</div>
|
||||
</div>
|
||||
{% for field in requestFields -%}
|
||||
{%- include 'blocks/field-row.html.twig' with {
|
||||
field: field,
|
||||
objectsLinks: objectsLinks
|
||||
} %}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
<div class="part-block">
|
||||
<a class="show-example-response">Пример запроса</a>
|
||||
</div>
|
||||
<div class="part-example-response">
|
||||
<div class="inputs">
|
||||
{% for field in requestFields -%}
|
||||
<label>
|
||||
{{ field.jsonName }}<br>
|
||||
{% if field.type.values is not empty -%}
|
||||
<div class="styled-select">
|
||||
<select data-name="{{ field.jsonName }}">
|
||||
{% for value in field.type.values %}
|
||||
<option>{{ value.value }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{%- else %}
|
||||
{%- if field.optional or field.nullable -%}
|
||||
<div class="styled-input">
|
||||
<input type="text" data-name="{{ field.jsonName }}">
|
||||
{% if field.optional -%}
|
||||
<div class="clear-btn">×</div>
|
||||
{%- endif -%}
|
||||
{% if field.nullable -%}
|
||||
<div class="null-btn">NULL</div>
|
||||
{%- endif %}
|
||||
</div>
|
||||
{%- else %}
|
||||
<input type="text" data-name="{{ field.jsonName }}">
|
||||
{% endif %}
|
||||
{%- endif %}
|
||||
</label>
|
||||
{% endfor %}
|
||||
|
||||
<button class="btn run-btn" data-server-method-path="{{ serverMethodPath }}">
|
||||
Выполнить
|
||||
</button>
|
||||
</div>
|
||||
<div class="text-response"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Возможные ошибки</h2>
|
||||
{% for value in errorsEnumeration.values -%}
|
||||
{%- if value.value in errorsEnumeration.allowedValues %}
|
||||
<p class="sub-header">#Код {{ value.value }} — {{ value.description }}</p>
|
||||
{%- endif -%}
|
||||
{%- endfor %}
|
||||
|
||||
<h2>Результат</h2>
|
||||
<p>Объект следующей структуры:</p>
|
||||
|
||||
<div class="table example-response-expanded">
|
||||
<div class="part-table">
|
||||
<div class="row-header">
|
||||
<div>Название поля</div>
|
||||
<div>Тип поля</div>
|
||||
<div class="text-centered">Описание</div>
|
||||
<div>Обязательность</div>
|
||||
</div>
|
||||
{% for field in responseFields -%}
|
||||
{%- include 'blocks/field-row.html.twig' with {
|
||||
field: field,
|
||||
objectsLinks: objectsLinks
|
||||
} %}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Комментарий</h2>
|
||||
<p class="sub-header">{{ description }}</p>
|
||||
{%- include 'blocks/method-body.html.twig' with {
|
||||
method: method,
|
||||
objectsLinks: objectsLinks
|
||||
} %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
const searchItems = {{ searchItems }};
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
<div class="title">{{ pageTitle }}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
{%- include 'blocks/main-menu.html.twig' %}
|
||||
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
|
||||
|
||||
<menu class="secondary">
|
||||
{% include 'blocks/secondary-menu.html.twig' with {
|
||||
|
|
@ -24,28 +24,14 @@
|
|||
</div>
|
||||
|
||||
<div class="aside aside-right">
|
||||
{%- include 'blocks/header.html.twig' with { imagesFolderPath: imagesFolderPath } %}
|
||||
{%- include 'blocks/header.html.twig' with {
|
||||
imagesFolderPath: imagesFolderPath,
|
||||
relativeToRootPath: relativeToRootPath
|
||||
} %}
|
||||
|
||||
<div class="content">
|
||||
<div class="page-data">
|
||||
<h2>Описание</h2>
|
||||
<p class="sub-header">{{ description }}</p>
|
||||
|
||||
<h2>Возможные значения</h2>
|
||||
<div class="table table--small">
|
||||
<div class="part-table">
|
||||
<div class="row-header">
|
||||
<div>Значения</div>
|
||||
<div>Описание</div>
|
||||
</div>
|
||||
{% for value in values %}
|
||||
<div class="row-body">
|
||||
<div>{{ value.value }}</div>
|
||||
<div>{{ value.description }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{%- include 'blocks/enum-body.html.twig' with { structure: structure } %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
<menu class="secondary">
|
||||
{% include 'blocks/secondary-menu.html.twig' with {
|
||||
menu: enumsMenu,
|
||||
menuTitle: "Перечисления"
|
||||
menuTitle: "Перечисления",
|
||||
activeItemTypeName: name
|
||||
} %}
|
||||
{% include 'blocks/secondary-menu.html.twig' with {
|
||||
menu: classesMenu,
|
||||
|
|
@ -25,32 +26,15 @@
|
|||
<div class="aside aside-right">
|
||||
{%- include 'blocks/header.html.twig' with {
|
||||
imagesFolderPath: imagesFolderPath,
|
||||
methodsPath: methodsPath,
|
||||
relativeToRootPath: relativeToRootPath
|
||||
} %}
|
||||
|
||||
<div class="content">
|
||||
<div class="page-data">
|
||||
<h2>Описание</h2>
|
||||
<p class="sub-header">{{ description }}</p>
|
||||
|
||||
<h2>Структура данных</h2>
|
||||
<div class="table">
|
||||
<div class="part-table">
|
||||
<div class="row-header">
|
||||
<div>Название поля</div>
|
||||
<div>Тип поля</div>
|
||||
<div class="text-centered">Описание</div>
|
||||
<div>Обязательность</div>
|
||||
</div>
|
||||
{% for field in allFieldsOrdered -%}
|
||||
{%- include 'blocks/field-row.html.twig' with {
|
||||
field: field,
|
||||
objectsLinks: objectsLinks
|
||||
} %}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{%- include 'blocks/class-body.html.twig' with {
|
||||
structure: structure,
|
||||
objectsLinks: objectsLinks
|
||||
} %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
{%- include 'blocks/head.html.twig' with { title: pageTitle, cssFolderPath: cssFolderPath } %}
|
||||
|
||||
<body class="main-page">
|
||||
<div class="aside aside-left">
|
||||
<div class="header">
|
||||
<div class="title">{{ pageTitle }}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="aside aside-right">
|
||||
{%- include 'blocks/header.html.twig' with {
|
||||
imagesFolderPath: imagesFolderPath,
|
||||
relativeToRootPath: relativeToRootPath
|
||||
} %}
|
||||
|
||||
<div class="content">
|
||||
<div class="page-data">
|
||||
{%- include 'blocks/table-of-contents-body.html.twig' with {
|
||||
methods: tableOfContents.methods,
|
||||
classes: tableOfContents.classes,
|
||||
enums: tableOfContents.enums
|
||||
} %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{%- include 'blocks/scripts.html.twig' with { jsFolderPath: jsFolderPath } %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
{%- include 'blocks/head.html.twig' with { title: pageTitle, cssFolderPath: cssFolderPath } %}
|
||||
|
||||
{# FIXME. Discuss: https://github.com/TouchInstinct/api-generator/issues/41 #}
|
||||
{%- set outOfDateError = first(errorType.values) -%}
|
||||
|
||||
<body class="main-page">
|
||||
<div class="aside aside-left">
|
||||
<div class="header">
|
||||
|
|
@ -23,7 +26,7 @@
|
|||
<p class="sub-header">Необходимо иметь возможность поддержки нескольких версий API (для одновременной работы нескольких версий приложения). Также необходимо предусмотреть принудительное обновление какой-либо из версий.</p>
|
||||
<p class="sub-header"> Версии API будут размещаться на url-адресах вида <base_url>/v<version_number>/, где <version_number> - версия API.</p>
|
||||
<p class="sub-header">При вызове любого метода в случае, если вызываемая версия API требует обновления приложения, сервер должен вернуть ошибку:<br/>
|
||||
"Версия приложения устарела. Необходимо обновить приложение. Код 1."</p>
|
||||
"{{ outOfDateError.description }} <a href="{{ errorsPagePath }}">Код {{ outOfDateError.value }}.</a>"</p>
|
||||
<p class="sub-header">При этом приложение должно показать пользователю диалог с предложением установить новую версию из маркета, а остальные функции должны стать недоступными.
|
||||
</p>
|
||||
|
||||
|
|
@ -33,24 +36,9 @@
|
|||
<div class="example-response">
|
||||
|
||||
<div class="text-response">{
|
||||
"response": <span class="text-digit"></span>{
|
||||
"count": <span class="text-digit">2428</span>,
|
||||
"items": <span class="text-digit"></span>
|
||||
[
|
||||
{
|
||||
"id": <span class="text-digit">54832560</span>,
|
||||
"first_name": <span class="text-digit"></span><span class="text-string">"Anyutka"</span>,
|
||||
"last_name": <span class="text-digit"></span><span class="text-string">"Kiseleva"</span>,
|
||||
"photo_50": <span class="text-digit"></span><span class="text-string">"http://cs417830.v...4a7/Y-zZa02zvmQ.jpg"</span>
|
||||
},
|
||||
{
|
||||
"id": <span class="text-digit">221194575</span>,
|
||||
"first_name": <span class="text-digit"></span><span class="text-string">"Lera"</span>,
|
||||
"last_name": <span class="text-digit"></span><span class="text-string">"Chistova"</span>,
|
||||
"photo_50": <span class="text-digit"></span><span class="text-string">"http://cs322328.v...0fb/qi2nofkqneI.jpg"</span>
|
||||
}
|
||||
]
|
||||
}
|
||||
"result": <span class="text-digit">null</span>
|
||||
"error_code": <span class="text-digit">{{ outOfDateError.value }}</span>,
|
||||
"error_message": <span class="text-digit">"{{ outOfDateError.description }}"</span>
|
||||
}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue