jekyll-theme-alta-docs 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -98
- data/_includes/feature_meta.html +50 -23
- data/_includes/features/rails/rails_resource_controller.md +167 -0
- data/_includes/features/rails/rails_resource_development.md +50 -0
- data/_includes/features/rails/rails_resource_model.md +57 -0
- data/_includes/features/rails/rails_resource_query.md +43 -0
- data/_includes/features/rails/rails_resource_routes.md +13 -0
- data/_includes/features/rails/rails_resource_serializer.md +26 -0
- data/_includes/features/react/api_service.md +131 -0
- data/_includes/features/react/app_init.md +103 -0
- data/_includes/guidelines/rails/api_only_psql_no_admin_setup_instructions.md +14 -0
- data/_includes/instructions/how_to_share_documentation.md +91 -0
- data/_includes/nav.html +15 -3
- data/_includes/project_overview.html +1 -1
- data/_includes/requirements_list.html +35 -0
- data/_includes/system_components_overview.html +1 -1
- data/_sass/jekyll-theme-alta-docs.scss +34 -0
- metadata +13 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cfe209fc6b38de2a86aa011b9b6c4ca07563e9da0f92fb0a0a0940d1bb2135f0
|
|
4
|
+
data.tar.gz: 52ef29832776dc1a37f4eb2692a1d0d83ea996c6cbfc91cfa65aaa9fca400558
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63ad959b450234ac1911d30e5004acf5ec0b66b3ccf9e527897bbbf137fcdf876510fb1526fd98d0b37eecd9fa82124d0fe4d4152cf14f4aac362b79263133ad
|
|
7
|
+
data.tar.gz: aa20a00e02103dffe3ba40d0b16a548e3b733228fd1d8976853dad8eb15a011cf2aa2ccd324f35043c2923c2c2dd89ea1d9a172391e2514a8c0fd8aa18559c4f
|
data/README.md
CHANGED
|
@@ -79,114 +79,27 @@ The Jekyll theme for documenting software development projects.
|
|
|
79
79
|
|
|
80
80
|
This is my home page
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
bundle exec jekyll serve
|
|
85
|
-
|
|
86
|
-
### What's next?
|
|
87
|
-
|
|
88
|
-
Add more documents in *_docs* folder and see [advanced options](#advanced-options).
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
## Advanced options
|
|
92
|
-
|
|
93
|
-
### Common _config.yml options
|
|
94
|
-
|
|
95
|
-
title : "Project title"
|
|
96
|
-
|
|
97
|
-
getting_started : >- # Used in the Project overview component
|
|
98
|
-
Take a look on the useful materials below.
|
|
99
|
-
Start by checking "the System Overview" to get a big picture of the project.
|
|
100
|
-
Don't forget to check "Development Guidelines".
|
|
101
|
-
Find more by exploring navigation on the left.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
### Links
|
|
106
|
-
|
|
107
|
-
Links to the repositories can be added in *_config.yml*:
|
|
108
|
-
|
|
109
|
-
links:
|
|
110
|
-
repos:
|
|
111
|
-
- name : Web app repository
|
|
112
|
-
icon : "fab fa-github" # Use fontawesome v6
|
|
113
|
-
url : https://bitbucket.org/
|
|
114
|
-
- name : Backend repository
|
|
115
|
-
icon : "fab fa-bitbucket" # Use fontawesome v6
|
|
116
|
-
url : https://bitbucket.org/
|
|
117
|
-
- name : Docs repository
|
|
118
|
-
icon : "fab fa-gitlab" # Use fontawesome v6
|
|
119
|
-
url : https://bitbucket.org/
|
|
120
|
-
useful:
|
|
121
|
-
- name : System overview
|
|
122
|
-
icon : "fas fa-project-diagram"
|
|
123
|
-
url : /architecture/
|
|
124
|
-
- name : Architecture
|
|
125
|
-
icon : "fas fa-clipboard-list"
|
|
126
|
-
url : /architecture/
|
|
127
|
-
- name : Development Guidelines
|
|
128
|
-
icon : "fas fa-pencil-alt"
|
|
129
|
-
url : /architecture/
|
|
130
|
-
|
|
131
|
-
Repositories links are displayed in website footer.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
### System components
|
|
135
|
-
|
|
136
|
-
You can define the system components like Backend, Frontend etc. in *_config.yml*:
|
|
82
|
+
... or:
|
|
137
83
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
- name: React.js
|
|
142
|
-
- name: Redux
|
|
143
|
-
- name : Backend
|
|
144
|
-
techs :
|
|
145
|
-
- name: Ruby on Rails
|
|
146
|
-
- name : Database
|
|
147
|
-
techs :
|
|
148
|
-
- name: PostgreSQL
|
|
149
|
-
- name : Service provider
|
|
150
|
-
techs :
|
|
151
|
-
- name: AWS
|
|
152
|
-
|
|
153
|
-
The "System components" are used in two components:
|
|
154
|
-
|
|
155
|
-
* `project_overview.html` > `{% include project_overview.html %}`
|
|
156
|
-
* `system_components_overview.html` > `{% include project_overview.html %}`
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
### Versioning
|
|
160
|
-
|
|
161
|
-
The documentation version is displayed in the footer.
|
|
162
|
-
|
|
163
|
-
doc_version : 1.0.0
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
## Components (includes)
|
|
84
|
+
---
|
|
85
|
+
layout: page
|
|
86
|
+
---
|
|
167
87
|
|
|
168
|
-
|
|
88
|
+
{% include project_overview.html next_button="/docs/development/" %}
|
|
169
89
|
|
|
170
|
-
The "Project overview" component renders:
|
|
171
90
|
|
|
172
|
-
|
|
173
|
-
* `doc_version`
|
|
174
|
-
* `description`
|
|
175
|
-
* `getting_started`
|
|
176
|
-
* `system_components`
|
|
177
|
-
* `links`
|
|
91
|
+
7. Run:
|
|
178
92
|
|
|
179
|
-
|
|
93
|
+
bundle exec jekyll serve
|
|
180
94
|
|
|
181
|
-
|
|
95
|
+
### What's next?
|
|
182
96
|
|
|
183
|
-
|
|
97
|
+
Add more documents in *_docs* folder and see [advanced options](docs/01_advanced_options.md).
|
|
184
98
|
|
|
185
|
-
{% include project_overview.html next_button="/docs/development/" %}
|
|
186
99
|
|
|
187
|
-
|
|
100
|
+
## Advanced options
|
|
188
101
|
|
|
189
|
-
|
|
102
|
+
See more: [advanced options](docs/01_advanced_options.md)
|
|
190
103
|
|
|
191
104
|
|
|
192
105
|
## Development
|
|
@@ -196,6 +109,11 @@ To set up your environment to develop this theme, run `bundle install`.
|
|
|
196
109
|
To test theme, run: `bundle exec rake preview` or `bundle exec rake preview host=xxx.xx.xxx.xx`
|
|
197
110
|
|
|
198
111
|
|
|
112
|
+
## Development todo's
|
|
113
|
+
|
|
114
|
+
Add more templates, integrations with *the source code*, setup scripts.
|
|
115
|
+
|
|
116
|
+
|
|
199
117
|
## License
|
|
200
118
|
|
|
201
119
|
The theme is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/_includes/feature_meta.html
CHANGED
|
@@ -1,30 +1,57 @@
|
|
|
1
|
-
{% if page.status
|
|
1
|
+
{% if page.status or page.prio or page.system_components or page.version or page.vtags or page.vtag %}
|
|
2
2
|
<div class='feature-meta'>
|
|
3
|
-
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
<
|
|
3
|
+
{% if page.vtags or page.vtag %}
|
|
4
|
+
<div class='feature-meta__version'>
|
|
5
|
+
<label>Tags:</label>
|
|
6
|
+
<div>
|
|
7
|
+
{% if page.vtag %}
|
|
8
|
+
<span class='tag tag--{{ page.vtag | replace: " ", "-" }} feature-meta__status--{{ page.vtag | replace: " ", "-" }}'>{{ page.vtag }}</span>
|
|
9
|
+
{% endif %}
|
|
10
|
+
{% if page.vtags %}
|
|
11
|
+
{% for vtag in page.vtags %}
|
|
12
|
+
<span class='tag tag--{{ vtag | replace: " ", "-" }} feature-meta__status--{{ vtag | replace: " ", "-" }}'>{{ vtag }}</span>
|
|
13
|
+
{% endfor %}
|
|
14
|
+
{% endif %}
|
|
15
|
+
</div>
|
|
7
16
|
</div>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<div>
|
|
12
|
-
<
|
|
17
|
+
{% endif %}
|
|
18
|
+
|
|
19
|
+
{% if page.status %}
|
|
20
|
+
<div class='feature-meta__status'>
|
|
21
|
+
<label>Status:</label>
|
|
22
|
+
<div>
|
|
23
|
+
<span class='tag tag--{{ page.status }} feature-meta__status--{{ page.status }}'>{{ page.status }}</span>
|
|
24
|
+
</div>
|
|
13
25
|
</div>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<div>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
{% endif %}
|
|
27
|
+
|
|
28
|
+
{% if page.prio %}
|
|
29
|
+
<div class='feature-meta__prio'>
|
|
30
|
+
<label>Priority:</label>
|
|
31
|
+
<div>
|
|
32
|
+
<span class='tag tag--{{ page.prio }} feature-meta__prio--{{ page.prio }}'>{{ page.prio }}</span>
|
|
33
|
+
</div>
|
|
21
34
|
</div>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<div>
|
|
26
|
-
<
|
|
35
|
+
{% endif %}
|
|
36
|
+
|
|
37
|
+
{% if page.system_components %}
|
|
38
|
+
<div class='feature-meta__system_components'>
|
|
39
|
+
<label>System components:</label>
|
|
40
|
+
<div>
|
|
41
|
+
{% for component in page.system_components %}
|
|
42
|
+
<span class='tag'>{{ component }}</span>
|
|
43
|
+
{% endfor %}
|
|
44
|
+
</div>
|
|
27
45
|
</div>
|
|
28
|
-
|
|
46
|
+
{% endif %}
|
|
47
|
+
|
|
48
|
+
{% if page.version %}
|
|
49
|
+
<div class='feature-meta__version'>
|
|
50
|
+
<label>Version:</label>
|
|
51
|
+
<div>
|
|
52
|
+
<span class='feature-meta__version'>{{ page.version }}</span>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
{% endif %}
|
|
29
56
|
</div>
|
|
30
57
|
{% endif %}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
{% assign model = include.model %}
|
|
2
|
+
{% assign namespace = include.namespace %}
|
|
3
|
+
|
|
4
|
+
{% assign tab = 0 %}
|
|
5
|
+
{% capture namespace_modules %}{% for n in namespace %}
|
|
6
|
+
{{ tab | indent }}module {{ n | camelcase }}{% assign tab = tab | plus:1 %}{% endfor %}{% endcapture %}
|
|
7
|
+
|
|
8
|
+
```ruby
|
|
9
|
+
# frozen_string_literal: true
|
|
10
|
+
|
|
11
|
+
{{ namespace_modules }}{% capture _ %}{% increment tab %}{% endcapture %}
|
|
12
|
+
{{ tab | indent }}# {{ model.db_name | capitalize }} controller{% assign tab = tab + ' ' %}
|
|
13
|
+
{{ tab | indent }}class {{ model.db_name | camelcase }}Controller < BaseController
|
|
14
|
+
resource_description do
|
|
15
|
+
short '{{ model.db_name | capitalize }}'
|
|
16
|
+
deprecated false
|
|
17
|
+
description <<-DES
|
|
18
|
+
{{ model.db_name | capitalize }} resource.
|
|
19
|
+
DES
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
before_action :set_{{ model.name}}, except: [:index, :create]
|
|
23
|
+
|
|
24
|
+
api :GET, '/{{ model.db_name }}', 'See {{ model.db_name }}'
|
|
25
|
+
returns code: 200, desc: '{{ model.name | capitalize }} details' do
|
|
26
|
+
property :status, String, desc: '200'
|
|
27
|
+
property :message, String, desc: '{{ model.db_name | capitalize }} details'
|
|
28
|
+
property :data, Hash, desc: '{{ model.db_name | capitalize }} data' do
|
|
29
|
+
property :page, Integer
|
|
30
|
+
property :total, Integer
|
|
31
|
+
property :{{ model.db_name }}, Array do{% for field in model.fields %}
|
|
32
|
+
property :{{ field.name }}, {{ field.type | camelcase }}{% endfor %}
|
|
33
|
+
property :created_at, DateTime
|
|
34
|
+
property :updated_at, DateTime
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
example <<-DES
|
|
39
|
+
# Request:
|
|
40
|
+
[GET] /{{ model.db_name }}/{:id}
|
|
41
|
+
DES
|
|
42
|
+
def index
|
|
43
|
+
# TODO: Pagination and filters
|
|
44
|
+
@{{ model.db_name }} = {{ model.name | camelcase }}.all
|
|
45
|
+
send_response(200, 'List of {{ model.db_name | capitalize }}', nil, ActiveModel::Serializer::CollectionSerializer.new(@{{ model.db_name }}, serializer: {{ model.name | camelcase }}Serializer))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
api :GET, '/{{ model.db_name }}/:id', 'See {{ model.name }} details'
|
|
49
|
+
param :id, String, desc: 'ID of the invitation', required: true
|
|
50
|
+
error code: 404, desc: 'NOT_FOUND'
|
|
51
|
+
returns code: 200, desc: '{{ model.name | capitalize }} details' do
|
|
52
|
+
property :status, String, desc: '200'
|
|
53
|
+
property :message, String, desc: '{{ model.name | capitalize }} details'
|
|
54
|
+
property :data, Hash, desc: '{{ model.name | capitalize }} data' do{% for field in model.fields %}
|
|
55
|
+
property :{{ field.name }}, {{ field.type | camelcase }}{% endfor %}
|
|
56
|
+
property :created_at, DateTime
|
|
57
|
+
property :updated_at, DateTime
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
example <<-DES
|
|
61
|
+
# Request:
|
|
62
|
+
[GET] /{{ model.db_name }}/{:id}
|
|
63
|
+
DES
|
|
64
|
+
def show
|
|
65
|
+
send_response(200, '{{ model.name | capitalize }} details', nil, {{ model.name | camelcase }}Serializer.new(@{{ model.name }}))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
api :POST, '/{{ model.db_name }}', 'Create {{ model.name }}'
|
|
69
|
+
error code: 422, desc: 'RESOURCE_NOT_VALID'
|
|
70
|
+
returns code: 200, desc: '{{ model.name | capitalize }} details' do
|
|
71
|
+
property :status, String, desc: '200'
|
|
72
|
+
property :message, String, desc: '{{ model.name | capitalize }} details'
|
|
73
|
+
property :data, Hash, desc: '{{ model.name | capitalize }} data' do{% for field in model.fields %}
|
|
74
|
+
property :{{ field.name }}, {{ field.type | camelcase }}{% endfor %}
|
|
75
|
+
property :created_at, DateTime
|
|
76
|
+
property :updated_at, DateTime
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
example <<-DES
|
|
80
|
+
# Request:
|
|
81
|
+
[GET] /{{ model.db_name }}/{:id}
|
|
82
|
+
DES
|
|
83
|
+
def create
|
|
84
|
+
# Add strong params
|
|
85
|
+
@{{ model.name }} = {{ model.name | camelcase }}.new({{ model.name }}_params)
|
|
86
|
+
if @{{ model.name }}.save
|
|
87
|
+
send_response(200, '{{ model.name | capitalize }} details', nil, {{ model.name | camelcase }}Serializer.new(@{{ model.name }}))
|
|
88
|
+
else
|
|
89
|
+
send_response(422, '{{ model.name | capitalize }} error', 'RESOURCE_NOT_VALID', @{{ model.name }}.errors))
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
api :PUT, '/{{ model.db_name }}/:id', 'Update {{ model.name }}'
|
|
94
|
+
param :id, String, desc: 'ID of the invitation', required: true
|
|
95
|
+
error code: 403, desc: 'RESOURCE_NOT_VALID'
|
|
96
|
+
error code: 404, desc: 'NOT_FOUND'
|
|
97
|
+
returns code: 200, desc: '{{ model.name | capitalize }} details' do
|
|
98
|
+
property :status, String, desc: '200'
|
|
99
|
+
property :message, String, desc: '{{ model.name | capitalize }} details'
|
|
100
|
+
property :data, Hash, desc: '{{ model.name | capitalize }} data' do{% for field in model.fields %}
|
|
101
|
+
property :{{ field.name }}, {{ field.type | camelcase }}{% endfor %}
|
|
102
|
+
property :created_at, DateTime
|
|
103
|
+
property :updated_at, DateTime
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
example <<-DES
|
|
107
|
+
# Request:
|
|
108
|
+
[GET] /{{ model.db_name }}/{:id}
|
|
109
|
+
DES
|
|
110
|
+
def update
|
|
111
|
+
# Add strong params
|
|
112
|
+
@{{ model.name }} = {{ model.name | camelcase }}.assign_attributes({{ model.name }}_params)
|
|
113
|
+
if @{{ model.name }}
|
|
114
|
+
if @{{ model.name }}.save
|
|
115
|
+
send_response(200, '{{ model.name | capitalize }} updated', nil, {{ model.name | camelcase }}Serializer.new(@{{ model.name }}))
|
|
116
|
+
else
|
|
117
|
+
send_response(403, '{{ model.name | capitalize }} error', 'RESOURCE_NOT_VALID', @{{ model.name }}))
|
|
118
|
+
end
|
|
119
|
+
else
|
|
120
|
+
send_response(404, '{{ model.name | capitalize }} not found', 'NOT_FOUND', nil))
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
api :DELETE, '/{{ model.db_name }}/:id', 'Delete {{ model.name }}'
|
|
125
|
+
param :id, String, desc: 'ID of the invitation', required: true
|
|
126
|
+
error code: 403, desc: 'RESOURCE_NOT_VALID'
|
|
127
|
+
error code: 404, desc: 'NOT_FOUND'
|
|
128
|
+
returns code: 200, desc: '{{ model.name | capitalize }} details' do
|
|
129
|
+
property :status, String, desc: '200'
|
|
130
|
+
property :message, String, desc: '{{ model.name | capitalize }} details'
|
|
131
|
+
property :data, Hash, desc: '{{ model.name | capitalize }} data' do{% for field in model.fields %}
|
|
132
|
+
property :{{ field.name }}, {{ field.type | camelcase }}{% endfor %}
|
|
133
|
+
property :created_at, DateTime
|
|
134
|
+
property :updated_at, DateTime
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
example <<-DES
|
|
138
|
+
# Request:
|
|
139
|
+
[GET] /{{ model.db_name }}/{:id}
|
|
140
|
+
DES
|
|
141
|
+
def destroy
|
|
142
|
+
if @{{ model.name }}
|
|
143
|
+
if @{{ model.name }}.destroy
|
|
144
|
+
send_response(200, '{{ model.name | capitalize }} deleted', nil, {{ model.name | camelcase }}Serializer.new(@{{ model.name }}))
|
|
145
|
+
else
|
|
146
|
+
send_response(403, '{{ model.name | capitalize }} error', 'RESOURCE_NOT_VALID', @{{ model.name }}.errors))
|
|
147
|
+
end
|
|
148
|
+
else
|
|
149
|
+
send_response(404, '{{ model.name | capitalize }} not found', 'NOT_FOUND', nil))
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
private
|
|
154
|
+
|
|
155
|
+
def set_{{ model.name }}
|
|
156
|
+
@{{ model.name }} = {{ model.name | camelcase }}.find(params['id'])
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def {{ model.name }}_params
|
|
160
|
+
params.require(:{{model.name}}).permit({% for f in model.fields %}:{{f.name}},{% endfor %})
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
{% assign model_name = include.model_name %}
|
|
3
|
+
{% assign model = null %}
|
|
4
|
+
|
|
5
|
+
{% if include.model %}
|
|
6
|
+
{% assign model = include.model %}
|
|
7
|
+
{% else %}
|
|
8
|
+
{% for m in site.data.models %}
|
|
9
|
+
{% if m.name == model_name %}
|
|
10
|
+
{% assign model = m %}
|
|
11
|
+
{% break %}
|
|
12
|
+
{% endif %}
|
|
13
|
+
{% endfor %}
|
|
14
|
+
{% endif %}
|
|
15
|
+
|
|
16
|
+
{% assign namespace = null %}
|
|
17
|
+
|
|
18
|
+
{% if include.namespace %}
|
|
19
|
+
{% assign namespace = include.namespace %}
|
|
20
|
+
{% endif %}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Model
|
|
24
|
+
|
|
25
|
+
{% include features/rails/rails_resource_model.md model=model %}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Controller
|
|
29
|
+
|
|
30
|
+
{% include features/rails/rails_resource_controller.md model=model namespace=namespace %}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Routes
|
|
34
|
+
|
|
35
|
+
{% include features/rails/rails_resource_routes.md model_name=model.db_name namespace=namespace %}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### Queries
|
|
39
|
+
|
|
40
|
+
{% include features/rails/rails_resource_query.md model=model %}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### Serializer
|
|
44
|
+
|
|
45
|
+
{% include features/rails/rails_resource_serializer.md model=model %}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Tests
|
|
49
|
+
|
|
50
|
+
TODO
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
|
|
2
|
+
{% assign model=include.model %}
|
|
3
|
+
|
|
4
|
+
{% include models/_model.html model=model %}
|
|
5
|
+
|
|
6
|
+
### Generate model
|
|
7
|
+
|
|
8
|
+
{% capture model_fields_cmd %}{% for field in model.fields %}{% if field.name != "id" %}{% if field.references %}{{ field.name | remove: '_id' }}:references {% else %}{{ field.name }}:{{ field.type }} {% endif %}{% endif %}{% endfor %}{% endcapture %}
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
$ rails g model {{ model.name | capitalize }} {{ model_fields_cmd }}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Migration:
|
|
15
|
+
|
|
16
|
+
{% capture model_migration_file %}{% for field in model.fields %}
|
|
17
|
+
{% if field.references %}t.references :{{ field.name }}, foreign_key: true, type: :uuid{% if !field.references_optional %}, null: true{% endif %}{% else %}{% if field.name != "id" %}t.{{ field.type }} :{{ field.name }}{% endif %}{% if field.default %}, default: {{ field.default}}{% endif %}{% endif %}{% endfor %}{% endcapture %}
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
# frozen_string_literal: true
|
|
21
|
+
|
|
22
|
+
# Creates User Identities
|
|
23
|
+
class Create{{ model.db_name | capitalize }} < ActiveRecord::Migration[6.0]
|
|
24
|
+
def change
|
|
25
|
+
create_table :{{ model.db_name }}, id: :uuid do |t|
|
|
26
|
+
{{ model_migration_file }}
|
|
27
|
+
|
|
28
|
+
t.timestamps
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### models/{{ model.name | capitalize }}.rb
|
|
35
|
+
|
|
36
|
+
{% capture model_relations %}{% for r in model.relations %}
|
|
37
|
+
{{ r.type }}: {{ r.resource }}{% if r.optional %}, optional: true{% endif %}{% endfor %}{% endcapture %}
|
|
38
|
+
|
|
39
|
+
{% capture model_validations %}{% for r in model.validations %}
|
|
40
|
+
validates :{{ r.field }}{% if r.presence %}, presence: true{% endif%}{% endfor %}{% endcapture %}
|
|
41
|
+
|
|
42
|
+
{% capture model_enums %}{% for r in model.fields %}{% if r.enum %}
|
|
43
|
+
enum {{ r.name }}: { {% for e in r.enum_values %}
|
|
44
|
+
{{ e.val }}: {{e.key}},{% endfor %}
|
|
45
|
+
}{% endif %}{% endfor %}{% endcapture %}
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
# frozen_string_literal: true
|
|
49
|
+
|
|
50
|
+
# {{ model.name | capitalize }} model
|
|
51
|
+
class {{ model.name | capitalize }} < ApplicationRecord
|
|
52
|
+
{{ model_validations }}
|
|
53
|
+
{{ model_relations }}
|
|
54
|
+
{{ model_enums }}
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{% assign model = include.model %}
|
|
2
|
+
|
|
3
|
+
`app/queries/{{ model.name }}_query.rb`
|
|
4
|
+
|
|
5
|
+
```ruby
|
|
6
|
+
# frozen_string_literal: true
|
|
7
|
+
|
|
8
|
+
# {{ model.name | camelcase }} search query
|
|
9
|
+
class {{ model.name | camelcase }}Query
|
|
10
|
+
# def initialize(params = {}, relation = {{ model.name | camelcase }}.left_outer_joins(
|
|
11
|
+
# :subscriptions
|
|
12
|
+
# ).preload(:acm_commodities, :acm_company, :acm_dot_numbers)
|
|
13
|
+
# )
|
|
14
|
+
def initialize(params = {}, relation = {})
|
|
15
|
+
@relation = relation
|
|
16
|
+
@params = params
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def all
|
|
20
|
+
@relation
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def search_{{ model.db_name }}
|
|
24
|
+
# by_city
|
|
25
|
+
# by_name(@params[:search])
|
|
26
|
+
@relation
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
# def by_city
|
|
32
|
+
# if @params[:city]
|
|
33
|
+
# @relation = @relation.where('{{ model.db_name}}.city ILIKE ?', "%#{@params[:city]}%")
|
|
34
|
+
# end
|
|
35
|
+
# end
|
|
36
|
+
#
|
|
37
|
+
# def by_name(name)
|
|
38
|
+
# if name
|
|
39
|
+
# @relation = @relation.where('{{ model.db_name}}.name ILIKE ?', "%#{@params[:name]}%")
|
|
40
|
+
# end
|
|
41
|
+
# end
|
|
42
|
+
end
|
|
43
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{% assign model_name = include.model_name %}
|
|
2
|
+
{% assign namespace = include.namespace %}
|
|
3
|
+
|
|
4
|
+
{% assign tab = 0 %}
|
|
5
|
+
{% capture namespace_modules %}{% for n in namespace %}
|
|
6
|
+
{{ tab | indent }}namespace :{{ n }} do{% assign tab = tab | plus:1 %}{% endfor %}{% endcapture %}
|
|
7
|
+
|
|
8
|
+
```ruby
|
|
9
|
+
{{ namespace_modules }}
|
|
10
|
+
resources :{{ model_name}}
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{% assign model = include.model %}
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
`app/serializers/{{model.name}}_serializer.rb`
|
|
5
|
+
|
|
6
|
+
```ruby
|
|
7
|
+
# frozen_string_literal: true
|
|
8
|
+
|
|
9
|
+
# {{ model.name | camelcase }} serializer
|
|
10
|
+
class {{ model.name | camelcase }}Serializer < ActiveModel::Serializer
|
|
11
|
+
attributes {% for f in model.fields %}:{{ f.name}},{% endfor %}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# belongs_to :resource
|
|
15
|
+
# has_many :resource
|
|
16
|
+
|
|
17
|
+
# def lat
|
|
18
|
+
# object.latlng.lat || nil
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# def lng
|
|
22
|
+
# object.latlng.lon || nil
|
|
23
|
+
# end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
```
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Network and API Services norms the way how the application sends HTTP requests.
|
|
2
|
+
The API Service overrides the Network service by setting the host URL and adding necessary headers.
|
|
3
|
+
|
|
4
|
+
### Network Service
|
|
5
|
+
|
|
6
|
+
Create file `src/services/NetworkService.js`:
|
|
7
|
+
|
|
8
|
+
```javascript
|
|
9
|
+
import axios from 'axios'
|
|
10
|
+
|
|
11
|
+
class NetworkService {
|
|
12
|
+
static async get(path, query, options) {
|
|
13
|
+
options = {
|
|
14
|
+
response: true,
|
|
15
|
+
queryStringParameters: {},
|
|
16
|
+
...options
|
|
17
|
+
}
|
|
18
|
+
return await axios({
|
|
19
|
+
url: query ? `${path}?${query}` : path,
|
|
20
|
+
method: 'get',
|
|
21
|
+
...options
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static async post(path, query, data, options) {
|
|
26
|
+
options = {
|
|
27
|
+
response: true,
|
|
28
|
+
queryStringParameters: {},
|
|
29
|
+
...options
|
|
30
|
+
}
|
|
31
|
+
return await axios({
|
|
32
|
+
url: query ? `${path}?${query}` : path,
|
|
33
|
+
data,
|
|
34
|
+
method: 'post',
|
|
35
|
+
...options
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static async put(path, query, data, options) {
|
|
40
|
+
options = {
|
|
41
|
+
response: true,
|
|
42
|
+
queryStringParameters: {},
|
|
43
|
+
...options
|
|
44
|
+
}
|
|
45
|
+
return await axios({
|
|
46
|
+
url: query ? `${path}?${query}` : path,
|
|
47
|
+
data,
|
|
48
|
+
method: 'put'
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static async delete(path, query) {
|
|
53
|
+
return await axios({
|
|
54
|
+
url: query ? `${path}?${query}` : path,
|
|
55
|
+
method: 'delete'
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default NetworkService
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
### API Service
|
|
67
|
+
|
|
68
|
+
Add API URL to the config file `src/config/config.js`:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
const prod = {
|
|
72
|
+
API_URL: 'https://domain.com/api/v1/',
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const dev = {
|
|
76
|
+
API_URL: 'http://xxx.xxx.xx.xx:4000/api/v1/',
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Create file `src/services/APIService.js`:
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
import config from '../config/config'
|
|
84
|
+
import NetworkService from './NetworkService'
|
|
85
|
+
// import AuthService from './AuthService' // Use to get Auth token to get an access to API
|
|
86
|
+
|
|
87
|
+
class APIService {
|
|
88
|
+
static async get(path, query, options = {}) {
|
|
89
|
+
/* const header = await AuthService.getAuthToken()
|
|
90
|
+
const options = Object.assign(options, {
|
|
91
|
+
headers: header
|
|
92
|
+
}) */
|
|
93
|
+
const opts = Object.assign(options, {})
|
|
94
|
+
const response = await NetworkService.get(config.BACKEND_URL + path, query, opts)
|
|
95
|
+
return response
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static async post(path, query, data, options = {}) {
|
|
99
|
+
/* const header = await AuthService.getAuthToken()
|
|
100
|
+
const options = Object.assign(options, {
|
|
101
|
+
headers: header
|
|
102
|
+
}) */
|
|
103
|
+
const opts = Object.assign(options, {})
|
|
104
|
+
const response = await NetworkService.post(config.BACKEND_URL + path, query, data, opts)
|
|
105
|
+
return response
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static async put(path, query, data, options = {}) {
|
|
109
|
+
/* const header = await AuthService.getAuthToken()
|
|
110
|
+
const options = Object.assign(options, {
|
|
111
|
+
headers: header
|
|
112
|
+
}) */
|
|
113
|
+
const opts = Object.assign(options, {})
|
|
114
|
+
const response = await NetworkService.put(config.BACKEND_URL + path, query, data, opts)
|
|
115
|
+
return response
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static async delete(path, options = {}) {
|
|
119
|
+
/* const header = await AuthService.getAuthToken()
|
|
120
|
+
const options = Object.assign(options, {
|
|
121
|
+
headers: header
|
|
122
|
+
}) */
|
|
123
|
+
const opts = Object.assign(opt, {})
|
|
124
|
+
const response = await NetworkService.delete(config.BACKEND_URL + path, opts)
|
|
125
|
+
return response
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export default APIService
|
|
130
|
+
|
|
131
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
|
|
2
|
+
The application should perform initialization on start.
|
|
3
|
+
|
|
4
|
+
The default strategy is to execute successive functions sequentially.
|
|
5
|
+
Each function is a step that performs one and specific action.
|
|
6
|
+
If the result is as expected, trigger next function. If the result is not as expected, stop the chain and return the response.
|
|
7
|
+
|
|
8
|
+
Responses:
|
|
9
|
+
|
|
10
|
+
```javascript
|
|
11
|
+
// SUCCESS
|
|
12
|
+
// Everything went OK. Handle the returned data, i.e. store the data in Redux with actions.
|
|
13
|
+
{
|
|
14
|
+
status: 0,
|
|
15
|
+
data: { ... }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ERROR
|
|
19
|
+
// Something went wrong and application cannot be loaded
|
|
20
|
+
{
|
|
21
|
+
status: 1,
|
|
22
|
+
error: 'API_UNREACHABLE', // The error code
|
|
23
|
+
data: { ... } // optional
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// REDIRECT
|
|
27
|
+
// The application should redirect the user
|
|
28
|
+
{
|
|
29
|
+
status: 2,
|
|
30
|
+
url: '/sign-in', // User has to be redirected
|
|
31
|
+
message: 'MESSAGE_CODE' // i.e. message to display to the user
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Plan
|
|
36
|
+
|
|
37
|
+
#### 1. Add initialization script
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
// src/Init.js
|
|
41
|
+
/**
|
|
42
|
+
* Initialization script loading functions in a sequence.
|
|
43
|
+
*
|
|
44
|
+
* Statuses:
|
|
45
|
+
* 0 - sequence has been halted. It may mean that there was an error during initialization
|
|
46
|
+
* 1 - initialized with success.
|
|
47
|
+
* 2 - redirection
|
|
48
|
+
*
|
|
49
|
+
* @returns
|
|
50
|
+
*/
|
|
51
|
+
class Init {
|
|
52
|
+
static init() {
|
|
53
|
+
return this.firstFunction()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static async firstFunction() {
|
|
57
|
+
if (true) {
|
|
58
|
+
return this.secondFunction()
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
status: 0,
|
|
62
|
+
message: 'APP_INITIALIZATION_FAILED',
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static async secondFunction() {
|
|
67
|
+
return {
|
|
68
|
+
status: 0,
|
|
69
|
+
message: 'SUCCESS',
|
|
70
|
+
data: { a: 1, b: 2 }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export default Init
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### 2. Execute initialization script:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
// src/App.jsx
|
|
82
|
+
import Init from './Init.js'
|
|
83
|
+
|
|
84
|
+
function App() {
|
|
85
|
+
const [initPerformed, setInitPerformed] = useState(false)
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (!initPerformed) {
|
|
88
|
+
initializeApp()
|
|
89
|
+
}
|
|
90
|
+
}, [initPerformed])
|
|
91
|
+
|
|
92
|
+
async function initializeApp() {
|
|
93
|
+
await Init.init()
|
|
94
|
+
// OR:
|
|
95
|
+
// const response = await Init.init()
|
|
96
|
+
// Do something with response.. (i.e. Set Redux), check status (0,1,2), etc.
|
|
97
|
+
setInitPerformed(true)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
(...)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
```
|
|
@@ -189,6 +189,20 @@ Rails.application.config.generators do |g|
|
|
|
189
189
|
end
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
+
Generate migration:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
$ rails g migration enable_uuid
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
class EnableUUID < ActiveRecord::Migration
|
|
200
|
+
def change
|
|
201
|
+
enable_extension 'pgcrypto'
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
```
|
|
205
|
+
|
|
192
206
|
|
|
193
207
|
#### Apipie
|
|
194
208
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
## How to share documentation
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### 1. Build project
|
|
5
|
+
|
|
6
|
+
1. Build Jekyll project:
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
$ bundle exec jekyll build
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
2. Copy/download the content of the `_site` folder.
|
|
13
|
+
|
|
14
|
+
3. You can also zip the content of `_site` folder before download:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
$ zip -r docs.zip _site/
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### 2. Share
|
|
22
|
+
|
|
23
|
+
The built project (the `_site` folder) is a static website.
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
#### 2.1 Open on the computer
|
|
27
|
+
|
|
28
|
+
Download the project on local computer, navigate to the folder and open the `index.html`.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
#### 2.2 Host on VPS
|
|
32
|
+
|
|
33
|
+
1. Copy files to the `/var/www/{project-name}` folder
|
|
34
|
+
2. Create a new file in `/etc/nginx/sites-available/{project-name}.conf`
|
|
35
|
+
3. Paste following configuration and adjust: port number, path to the `/var/www/{project-name}`
|
|
36
|
+
|
|
37
|
+
server {
|
|
38
|
+
listen 4004 default_server;
|
|
39
|
+
listen [::]:4004 default_server;
|
|
40
|
+
|
|
41
|
+
root /var/www/{project-name};
|
|
42
|
+
|
|
43
|
+
server_name _;
|
|
44
|
+
|
|
45
|
+
location / {
|
|
46
|
+
# First attempt to serve request as file, then as directory, then fall back to displaying a 404.
|
|
47
|
+
try_files $uri $uri/ =404;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
4. Add symlink
|
|
52
|
+
|
|
53
|
+
$ ln -s /etc/nginx/sites-available/{project-name}.conf /etc/nginx/sites-enabled/
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
5. Test configuration
|
|
57
|
+
|
|
58
|
+
$ nginx -t
|
|
59
|
+
|
|
60
|
+
6. Reload NGINX
|
|
61
|
+
|
|
62
|
+
$ systemctl reload nginx
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
##### 2.2.1 Add basic auth
|
|
66
|
+
|
|
67
|
+
1. Verify that apache2-utils (Debian, Ubuntu) or httpd-tools (RHEL/CentOS/Oracle Linux) is installed.
|
|
68
|
+
|
|
69
|
+
2. Create credentials
|
|
70
|
+
|
|
71
|
+
$ sudo htpasswd -c /etc/nginx/.htpasswd user1
|
|
72
|
+
|
|
73
|
+
3. Edit `/etc/nginx/sites-available/{project-name}.conf`
|
|
74
|
+
|
|
75
|
+
location / {
|
|
76
|
+
auth_basic "Private Property";
|
|
77
|
+
auth_basic_user_file /etc/nginx/.htpasswd;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
4. Test configuration and reload nginx
|
|
81
|
+
|
|
82
|
+
$ nginx -t
|
|
83
|
+
$ systemctl reload nginx
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
#### 2.3 Host on the AWS S3
|
|
87
|
+
|
|
88
|
+
1. Create new bucket
|
|
89
|
+
2. Upload files
|
|
90
|
+
3. Set up ACL, permissions, CORS
|
|
91
|
+
4. Set up S3 bucket as hosting
|
data/_includes/nav.html
CHANGED
|
@@ -38,10 +38,22 @@
|
|
|
38
38
|
<li{{ current }}>
|
|
39
39
|
<a href="{{ site.baseurl }}{{ doc.url }}" class='ad-nav-link'>
|
|
40
40
|
<span class='title'>{{ doc.title }}</span>
|
|
41
|
-
{% if doc.status
|
|
41
|
+
{% if doc.status or doc.prio or doc.version or doc.vtags or doc.vtag %}
|
|
42
42
|
<div class='doc-meta-nav'>
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
{% if doc.status %}
|
|
44
|
+
<span class='tag tag--{{ doc.status }} feature-meta__status--{{ doc.status }}'>{{ doc.status }}</span>
|
|
45
|
+
{% endif %}
|
|
46
|
+
{% if doc.prio %}
|
|
47
|
+
<span class='tag tag--{{ doc.prio }} feature-meta__status--{{ doc.prio }}'>{{ doc.prio }}</span>
|
|
48
|
+
{% endif %}
|
|
49
|
+
{% if doc.vtag %}
|
|
50
|
+
<span class='tag tag--{{ doc.vtag | replace: " ", "-" }} feature-meta__status--{{ doc.vtag | replace: " ", "-" }}'>{{ doc.vtag }}</span>
|
|
51
|
+
{% endif %}
|
|
52
|
+
{% if doc.vtags %}
|
|
53
|
+
{% for vtag in doc.vtags %}
|
|
54
|
+
<span class='tag tag--{{ vtag | replace: " ", "-" }} feature-meta__status--{{ vtag | replace: " ", "-" }}'>{{ vtag }}</span>
|
|
55
|
+
{% endfor %}
|
|
56
|
+
{% endif %}
|
|
45
57
|
<span class='version'>{{ doc.version }}</span>
|
|
46
58
|
</div>
|
|
47
59
|
{% endif %}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{% assign rlist = include.list %}
|
|
2
|
+
{% assign rtitle = include.title %}
|
|
3
|
+
{% if rtitle %}
|
|
4
|
+
<h2>{{ rtitle | upcase }}</h2>
|
|
5
|
+
{% endif %}
|
|
6
|
+
|
|
7
|
+
<div class="requirements-list">
|
|
8
|
+
{% for r in rlist %}
|
|
9
|
+
<div class="requirements-list__item">
|
|
10
|
+
{% if r.status %}
|
|
11
|
+
<span class="requirements-list__status tag">{{ r.status }}</span>
|
|
12
|
+
{% endif %}
|
|
13
|
+
|
|
14
|
+
<h3><span class="requirements-list__id">{{ r.id }}</span> {{ r.title }}</h3>
|
|
15
|
+
|
|
16
|
+
{% if r.description %}
|
|
17
|
+
<p>{{ r.description }}</p>
|
|
18
|
+
{% endif %}
|
|
19
|
+
|
|
20
|
+
{% if r.links %}
|
|
21
|
+
<ul class="links">
|
|
22
|
+
{% for l in r.links %}
|
|
23
|
+
{% assign link_name = l.source %}
|
|
24
|
+
{% if l.name %}
|
|
25
|
+
{% assign link_name = l.name %}
|
|
26
|
+
{% endif %}
|
|
27
|
+
<li>
|
|
28
|
+
<a href="{{ l.source }}">{{ link_name }}</a>
|
|
29
|
+
</li>
|
|
30
|
+
{% endfor %}
|
|
31
|
+
</ul>
|
|
32
|
+
{% endif %}
|
|
33
|
+
</div>
|
|
34
|
+
{% endfor %}
|
|
35
|
+
</div>
|
|
@@ -354,6 +354,7 @@ button.ad-collapsible, .ad-collapsible {
|
|
|
354
354
|
|
|
355
355
|
.ad-doc__content {
|
|
356
356
|
padding: 15px;
|
|
357
|
+
max-width: 800px;
|
|
357
358
|
|
|
358
359
|
img {
|
|
359
360
|
max-width: 100%;
|
|
@@ -510,6 +511,13 @@ button.ad-collapsible, .ad-collapsible {
|
|
|
510
511
|
&.tag--high {
|
|
511
512
|
background: #F20455;
|
|
512
513
|
}
|
|
514
|
+
|
|
515
|
+
&.tag--epic {
|
|
516
|
+
background: #0392CC;
|
|
517
|
+
}
|
|
518
|
+
&.tag--user-story {
|
|
519
|
+
background: #ABC9B8;
|
|
520
|
+
}
|
|
513
521
|
}
|
|
514
522
|
|
|
515
523
|
.ad-nav-link {
|
|
@@ -576,6 +584,31 @@ button.ad-collapsible, .ad-collapsible {
|
|
|
576
584
|
}
|
|
577
585
|
}
|
|
578
586
|
|
|
587
|
+
.requirements-list {
|
|
588
|
+
padding-top: 40px;
|
|
589
|
+
padding-bottom: 40px;
|
|
590
|
+
.requirements-list__item {
|
|
591
|
+
border-bottom: 1px solid $gray-200;
|
|
592
|
+
padding-top: 20px;
|
|
593
|
+
padding-bottom: 20px;
|
|
594
|
+
h4 {
|
|
595
|
+
margin-top: 0px;
|
|
596
|
+
}
|
|
597
|
+
.requirements-list__id {
|
|
598
|
+
font-size: 10px;
|
|
599
|
+
color: $primary-color;
|
|
600
|
+
}
|
|
601
|
+
ul.links {
|
|
602
|
+
margin-top: 20px;
|
|
603
|
+
list-style: none;
|
|
604
|
+
padding-left: 0;
|
|
605
|
+
margin-top: 3px;
|
|
606
|
+
margin-bottom: 3px;
|
|
607
|
+
font-size: 14px;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
579
612
|
code.highlighter-rouge {
|
|
580
613
|
background: $code-bg;
|
|
581
614
|
padding: 1px 3px;
|
|
@@ -588,6 +621,7 @@ pre.highlight {
|
|
|
588
621
|
background: $code-bg;
|
|
589
622
|
border: 1px solid $gray-400;
|
|
590
623
|
border-radius: 3px;
|
|
624
|
+
overflow-x: auto;
|
|
591
625
|
.k {
|
|
592
626
|
color: #e00bbc;
|
|
593
627
|
font-weight: bold;
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-theme-alta-docs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tom Antas
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-11-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jekyll
|
|
@@ -90,6 +90,14 @@ files:
|
|
|
90
90
|
- LICENSE.txt
|
|
91
91
|
- README.md
|
|
92
92
|
- _includes/feature_meta.html
|
|
93
|
+
- _includes/features/rails/rails_resource_controller.md
|
|
94
|
+
- _includes/features/rails/rails_resource_development.md
|
|
95
|
+
- _includes/features/rails/rails_resource_model.md
|
|
96
|
+
- _includes/features/rails/rails_resource_query.md
|
|
97
|
+
- _includes/features/rails/rails_resource_routes.md
|
|
98
|
+
- _includes/features/rails/rails_resource_serializer.md
|
|
99
|
+
- _includes/features/react/api_service.md
|
|
100
|
+
- _includes/features/react/app_init.md
|
|
93
101
|
- _includes/footer.html
|
|
94
102
|
- _includes/guidelines/rails/api_only_project_tree.md
|
|
95
103
|
- _includes/guidelines/rails/api_only_project_tree_with_files.md
|
|
@@ -100,11 +108,13 @@ files:
|
|
|
100
108
|
- _includes/guidelines/react/react_project_tree.md
|
|
101
109
|
- _includes/head.html
|
|
102
110
|
- _includes/head_scripts.html
|
|
111
|
+
- _includes/instructions/how_to_share_documentation.md
|
|
103
112
|
- _includes/models/_model.html
|
|
104
113
|
- _includes/models/_models_list.html
|
|
105
114
|
- _includes/nav.html
|
|
106
115
|
- _includes/navbar.html
|
|
107
116
|
- _includes/project_overview.html
|
|
117
|
+
- _includes/requirements_list.html
|
|
108
118
|
- _includes/scripts.html
|
|
109
119
|
- _includes/sidebar.html
|
|
110
120
|
- _includes/system_components_overview.html
|
|
@@ -139,5 +149,5 @@ requirements: []
|
|
|
139
149
|
rubygems_version: 3.0.3
|
|
140
150
|
signing_key:
|
|
141
151
|
specification_version: 4
|
|
142
|
-
summary: The Jekyll theme for documenting software development projects
|
|
152
|
+
summary: The Jekyll theme for documenting software development projects.
|
|
143
153
|
test_files: []
|