lcms-engine 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (374) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -1
  3. data/.dockerignore +25 -0
  4. data/.env.docker +1 -1
  5. data/.eslintignore +2 -1
  6. data/.eslintrc +23 -73
  7. data/.nvmrc +1 -1
  8. data/.overcommit.yml +8 -2
  9. data/.prettierrc +7 -0
  10. data/.rubocop.yml +12 -8
  11. data/.ruby-version +1 -1
  12. data/.stylelintignore +9 -0
  13. data/.stylelintrc +8 -0
  14. data/CHANGELOG.md +50 -1
  15. data/Dockerfile +3 -3
  16. data/Gemfile.lock +408 -322
  17. data/README.md +20 -17
  18. data/app/assets/config/lcms_engine_manifest.js +4 -2
  19. data/app/assets/javascripts/lcms/engine/admin/{application.js → lcms_engine_application.js} +1 -3
  20. data/app/assets/javascripts/lcms/engine/initializers/foundation.js +1 -1
  21. data/app/assets/javascripts/lcms/engine/{application.js → lcms_engine_application.js} +0 -0
  22. data/app/assets/stylesheets/lcms/engine/admin/collections.scss +2 -1
  23. data/app/assets/stylesheets/lcms/engine/admin/components.scss +60 -19
  24. data/app/assets/stylesheets/lcms/engine/admin/curriculums.scss +12 -10
  25. data/app/assets/stylesheets/lcms/engine/admin/lessons.scss +21 -15
  26. data/app/assets/stylesheets/lcms/engine/admin/materials.scss +25 -17
  27. data/app/assets/stylesheets/lcms/engine/admin/resources.scss +8 -7
  28. data/app/assets/stylesheets/lcms/engine/admin/standards.scss +4 -1
  29. data/app/assets/stylesheets/lcms/engine/admin/users.scss +1 -1
  30. data/app/assets/stylesheets/lcms/engine/base/_colors.scss +8 -10
  31. data/app/assets/stylesheets/lcms/engine/base/_ld-colors.scss +10 -10
  32. data/app/assets/stylesheets/lcms/engine/components/_assoc-picker.scss +4 -5
  33. data/app/assets/stylesheets/lcms/engine/components/lesson/_activity.scss +6 -2
  34. data/app/assets/stylesheets/lcms/engine/components/lesson/_callout.scss +19 -5
  35. data/app/assets/stylesheets/lcms/engine/components/lesson/_columns.scss +4 -3
  36. data/app/assets/stylesheets/lcms/engine/components/lesson/_curriculum-map.scss +16 -7
  37. data/app/assets/stylesheets/lcms/engine/components/lesson/_def.scss +2 -2
  38. data/app/assets/stylesheets/lcms/engine/components/lesson/_expand.scss +9 -9
  39. data/app/assets/stylesheets/lcms/engine/components/lesson/_foundational-divider.scss +0 -1
  40. data/app/assets/stylesheets/lcms/engine/components/lesson/_group.scss +3 -1
  41. data/app/assets/stylesheets/lcms/engine/components/lesson/_icons.scss +1 -1
  42. data/app/assets/stylesheets/lcms/engine/components/lesson/_image-wrap.scss +2 -2
  43. data/app/assets/stylesheets/lcms/engine/components/lesson/_inset.scss +7 -2
  44. data/app/assets/stylesheets/lcms/engine/components/lesson/_materials.scss +1 -1
  45. data/app/assets/stylesheets/lcms/engine/components/lesson/_multiple-choice.scss +4 -1
  46. data/app/assets/stylesheets/lcms/engine/components/lesson/_override.scss +28 -9
  47. data/app/assets/stylesheets/lcms/engine/components/lesson/_pd.scss +7 -7
  48. data/app/assets/stylesheets/lcms/engine/components/lesson/_pv.scss +5 -4
  49. data/app/assets/stylesheets/lcms/engine/components/lesson/_section.scss +10 -3
  50. data/app/assets/stylesheets/lcms/engine/components/lesson/_selection-control.scss +14 -8
  51. data/app/assets/stylesheets/lcms/engine/components/lesson/_sidebar.scss +25 -10
  52. data/app/assets/stylesheets/lcms/engine/components/lesson/_title.scss +3 -1
  53. data/app/assets/stylesheets/lcms/engine/components/lesson/_unit-map.scss +1 -1
  54. data/app/assets/stylesheets/lcms/engine/components/material/_material.scss +3 -3
  55. data/app/assets/stylesheets/lcms/engine/components/material/_overlay.scss +12 -4
  56. data/app/assets/stylesheets/lcms/engine/components/material/_preview.scss +1 -1
  57. data/app/assets/stylesheets/lcms/engine/components/support/_survey.scss +3 -1
  58. data/app/assets/stylesheets/lcms/engine/layout/_footer.scss +29 -11
  59. data/app/assets/stylesheets/lcms/engine/layout/_header.scss +5 -5
  60. data/app/assets/stylesheets/lcms/engine/layout/_navigation.scss +4 -6
  61. data/app/assets/stylesheets/lcms/engine/layout/_page.scss +2 -2
  62. data/app/assets/stylesheets/lcms/engine/{admin.scss → lcms_engine_admin.scss} +26 -15
  63. data/app/assets/stylesheets/lcms/engine/lcms_engine_application.scss +9 -0
  64. data/app/assets/stylesheets/lcms/engine/pdf.scss +5 -26
  65. data/app/assets/stylesheets/lcms/engine/pdf_plain.scss +5 -23
  66. data/app/assets/stylesheets/lcms/engine/print/_base.scss +41 -12
  67. data/app/assets/stylesheets/lcms/engine/print/_cover.scss +12 -12
  68. data/app/assets/stylesheets/lcms/engine/print/_footer.scss +8 -3
  69. data/app/assets/stylesheets/lcms/engine/print/_gdoc-base.scss +10 -37
  70. data/app/assets/stylesheets/lcms/engine/print/_helpers.scss +5 -2
  71. data/app/assets/stylesheets/lcms/engine/print/_lesson-base.scss +2 -14
  72. data/app/assets/stylesheets/lcms/engine/print/_material-base.scss +1 -3
  73. data/app/assets/stylesheets/lcms/engine/print/_print.scss +15 -8
  74. data/app/assets/stylesheets/lcms/engine/print/_toc.scss +24 -9
  75. data/app/assets/stylesheets/lcms/engine/print/gdoc/_base-typography.scss +24 -6
  76. data/app/assets/stylesheets/lcms/engine/print/gdoc/_base.scss +10 -3
  77. data/app/assets/stylesheets/lcms/engine/print/gdoc/_colors.scss +3 -3
  78. data/app/assets/stylesheets/lcms/engine/print/gdoc/_header.scss +2 -2
  79. data/app/assets/stylesheets/lcms/engine/print/gdoc/_helpers.scss +1 -0
  80. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_activity.scss +1 -1
  81. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_agenda.scss +8 -2
  82. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_callout.scss +16 -6
  83. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_def.scss +1 -1
  84. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_dialogue.scss +3 -1
  85. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_expand.scss +5 -2
  86. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_image-wrap.scss +5 -3
  87. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_image.scss +1 -1
  88. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_optbreak.scss +1 -0
  89. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_section.scss +4 -1
  90. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_smp.scss +1 -0
  91. data/app/assets/stylesheets/lcms/engine/print/gdoc/lesson/_tables.scss +11 -3
  92. data/app/assets/stylesheets/lcms/engine/print/gdoc/material/_header.scss +5 -2
  93. data/app/assets/stylesheets/lcms/engine/print/lesson/_base-typography.scss +33 -9
  94. data/app/assets/stylesheets/lcms/engine/print/lesson/_group.scss +3 -1
  95. data/app/assets/stylesheets/lcms/engine/print/lesson/_image.scss +3 -1
  96. data/app/assets/stylesheets/lcms/engine/print/lesson/_materials.scss +1 -1
  97. data/app/assets/stylesheets/lcms/engine/print/lesson/_pd.scss +8 -4
  98. data/app/assets/stylesheets/lcms/engine/print/lesson/_section.scss +1 -1
  99. data/app/assets/stylesheets/lcms/engine/print/material/_header.scss +4 -1
  100. data/app/assets/stylesheets/lcms/engine/themes/_material.scss +11 -11
  101. data/app/assets/stylesheets/lcms/engine/utils/_colorcodes.scss +15 -5
  102. data/app/assets/stylesheets/lcms/engine/utils/_functions.scss +1 -1
  103. data/app/assets/stylesheets/lcms/engine/utils/_helpers.scss +23 -11
  104. data/app/assets/stylesheets/lcms/engine/utils/_placeholders.scss +1 -1
  105. data/app/assets/stylesheets/lcms/engine/utils/_variables.scss +11 -11
  106. data/app/assets/stylesheets/lcms/engine/vendors/{mathjax.css → mathjax.scss} +0 -0
  107. data/app/assets/stylesheets/lcms/engine/vendors/react-tagsinput.css +48 -0
  108. data/app/controllers/concerns/lcms/engine/reimportable.rb +12 -2
  109. data/app/controllers/lcms/engine/admin/access_codes_controller.rb +8 -3
  110. data/app/controllers/lcms/engine/admin/admin_controller.rb +6 -40
  111. data/app/controllers/lcms/engine/admin/association_picker_controller.rb +4 -1
  112. data/app/controllers/lcms/engine/admin/batch_reimports_controller.rb +2 -2
  113. data/app/controllers/lcms/engine/admin/curriculums_controller.rb +21 -2
  114. data/app/controllers/lcms/engine/admin/documents_controller.rb +41 -14
  115. data/app/controllers/lcms/engine/admin/materials_controller.rb +32 -13
  116. data/app/controllers/lcms/engine/admin/resource_bulk_edits_controller.rb +2 -2
  117. data/app/controllers/lcms/engine/admin/resources_controller.rb +9 -7
  118. data/app/controllers/lcms/engine/admin/settings_controller.rb +1 -1
  119. data/app/controllers/lcms/engine/admin/standards_controller.rb +7 -2
  120. data/app/controllers/lcms/engine/admin/users_controller.rb +15 -7
  121. data/app/controllers/lcms/engine/application_controller.rb +1 -1
  122. data/app/controllers/lcms/engine/resources_controller.rb +5 -5
  123. data/app/controllers/lcms/engine/welcome_controller.rb +11 -0
  124. data/app/entities/lcms/engine/grades.rb +17 -6
  125. data/app/entities/lcms/engine/hierarchical_position.rb +1 -2
  126. data/app/entities/lcms/engine/media_embed.rb +2 -2
  127. data/app/entities/lcms/engine/pagination.rb +14 -10
  128. data/app/entities/lcms/engine/roman_numerals.rb +2 -2
  129. data/app/exceptions/lcms/engine/document_error.rb +8 -0
  130. data/app/exceptions/lcms/engine/material_error.rb +8 -0
  131. data/app/forms/lcms/engine/document_form.rb +19 -14
  132. data/app/forms/lcms/engine/material_form.rb +3 -2
  133. data/app/helpers/admin/components_helper.rb +3 -3
  134. data/app/helpers/lcms/engine/path_helper.rb +32 -0
  135. data/app/helpers/lcms/engine/resource_helper.rb +1 -1
  136. data/app/helpers/lcms/engine/view_helper.rb +1 -9
  137. data/app/interactors/lcms/engine/explore_curriculum_interactor.rb +2 -2
  138. data/app/javascript/components/admin/ImportStatus.jsx +90 -56
  139. data/app/javascript/components/admin/Initializer.jsx +33 -35
  140. data/app/javascript/components/admin/MultiSelectedOperation.jsx +43 -18
  141. data/app/javascript/components/admin/association-picker/AssociationPicker.jsx +68 -47
  142. data/app/javascript/components/admin/association-picker/AssociationPickerItem.jsx +18 -7
  143. data/app/javascript/components/admin/association-picker/AssociationPickerResults.jsx +42 -17
  144. data/app/javascript/components/admin/association-picker/AssociationPickerWindow.jsx +47 -27
  145. data/app/javascript/components/admin/curriculum/CurriculumEditor.jsx +54 -32
  146. data/app/javascript/components/admin/curriculum/DirectoryPicker.jsx +80 -53
  147. data/app/javascript/components/admin/picker/PickerButton.jsx +16 -11
  148. data/app/javascript/components/admin/picker/pickerModal.jsx +6 -6
  149. data/app/javascript/components/admin/picker/pickerWindowWrapper.jsx +61 -40
  150. data/app/javascript/components/admin/resource-picker/ResourcePicker.jsx +54 -39
  151. data/app/javascript/components/admin/resource-picker/ResourcePickerResource.jsx +14 -3
  152. data/app/javascript/components/admin/resource-picker/ResourcePickerWindow.jsx +50 -21
  153. data/app/javascript/components/paginate/PageView.jsx +20 -8
  154. data/app/javascript/components/paginate/PaginationBoxView.jsx +78 -66
  155. data/app/javascript/components/paginate/PaginationListView.jsx +59 -45
  156. data/app/javascript/packs/lcms_engine_admin.js +15 -0
  157. data/app/javascript/packs/{application.js → lcms_engine_application.js} +5 -4
  158. data/app/javascript/packs/server_rendering.js +1 -0
  159. data/app/javascript/vendor/jstree/jstree.min.js +6 -0
  160. data/app/javascript/vendor/jstree/themes/default/32px.png +0 -0
  161. data/app/javascript/vendor/jstree/themes/default/40px.png +0 -0
  162. data/app/javascript/vendor/jstree/themes/default/style.css +1106 -0
  163. data/app/javascript/vendor/jstree/themes/default/style.min.css +1 -0
  164. data/app/javascript/vendor/jstree/themes/default/throbber.gif +0 -0
  165. data/app/javascript/vendor/jstree/themes/default-dark/32px.png +0 -0
  166. data/app/javascript/vendor/jstree/themes/default-dark/40px.png +0 -0
  167. data/app/javascript/vendor/jstree/themes/default-dark/style.css +1150 -0
  168. data/app/javascript/vendor/jstree/themes/default-dark/style.min.css +1 -0
  169. data/app/javascript/vendor/jstree/themes/default-dark/throbber.gif +0 -0
  170. data/app/jobs/concerns/lcms/engine/nested_resque_job.rb +1 -4
  171. data/app/jobs/lcms/engine/document_generate_gdoc_job.rb +2 -2
  172. data/app/jobs/lcms/engine/document_generate_job.rb +2 -2
  173. data/app/jobs/lcms/engine/document_generate_pdf_job.rb +5 -5
  174. data/app/jobs/lcms/engine/document_parse_job.rb +1 -1
  175. data/app/jobs/lcms/engine/material_generate_pdf_job.rb +4 -4
  176. data/app/models/concerns/lcms/engine/navigable.rb +6 -10
  177. data/app/models/concerns/lcms/engine/searchable.rb +7 -0
  178. data/app/models/lcms/engine/document.rb +1 -1
  179. data/app/models/lcms/engine/download.rb +1 -1
  180. data/app/models/lcms/engine/resource.rb +1 -1
  181. data/app/models/lcms/engine/search/document.rb +4 -3
  182. data/app/models/lcms/engine/search/repository.rb +1 -1
  183. data/app/presenters/lcms/engine/content_presenter.rb +1 -1
  184. data/app/presenters/lcms/engine/curriculum_presenter.rb +21 -18
  185. data/app/presenters/lcms/engine/document_presenter.rb +5 -3
  186. data/app/presenters/lcms/engine/resource_presenter.rb +6 -3
  187. data/app/queries/lcms/engine/admin_documents_query.rb +2 -2
  188. data/app/queries/lcms/engine/admin_materials_query.rb +11 -2
  189. data/app/queries/lcms/engine/base_query.rb +1 -1
  190. data/app/serializers/lcms/engine/previews_material_serializer.rb +1 -0
  191. data/app/services/lcms/engine/document_build_service.rb +6 -0
  192. data/app/services/lcms/engine/document_generator.rb +2 -2
  193. data/app/services/lcms/engine/google/drive_service.rb +7 -15
  194. data/app/services/lcms/engine/google/script_service.rb +7 -3
  195. data/app/services/lcms/engine/html_sanitizer.rb +6 -6
  196. data/app/services/lcms/engine/lessons_gdoc_bundler.rb +1 -1
  197. data/app/services/lcms/engine/lti_exporter.rb +1 -1
  198. data/app/services/lcms/engine/material_build_service.rb +6 -2
  199. data/app/services/lcms/engine/material_preview_generator.rb +3 -3
  200. data/app/services/lcms/engine/react_materials_resolver.rb +3 -2
  201. data/app/services/lcms/engine/s3_service.rb +14 -2
  202. data/app/tasks/resource_tasks.rb +2 -2
  203. data/app/views/layouts/lcms/engine/admin.html.erb +3 -3
  204. data/app/views/layouts/lcms/engine/application.html.erb +2 -2
  205. data/app/views/layouts/lcms/engine/lti.html.erb +1 -1
  206. data/app/views/lcms/engine/admin/access_codes/_form.html.erb +1 -1
  207. data/app/views/lcms/engine/admin/access_codes/index.html.erb +3 -3
  208. data/app/views/lcms/engine/admin/batch_reimports/_search_form.html.erb +2 -2
  209. data/app/views/lcms/engine/admin/curriculums/edit.html.erb +5 -5
  210. data/app/views/lcms/engine/admin/documents/_materials_links.html.erb +2 -2
  211. data/app/views/lcms/engine/admin/documents/_reimport.html.erb +1 -1
  212. data/app/views/lcms/engine/admin/documents/_search_form.html.erb +2 -2
  213. data/app/views/lcms/engine/admin/documents/import.html.erb +1 -1
  214. data/app/views/lcms/engine/admin/documents/index.html.erb +7 -5
  215. data/app/views/lcms/engine/admin/documents/new.html.erb +6 -2
  216. data/app/views/lcms/engine/admin/materials/_reimport.html.erb +1 -1
  217. data/app/views/lcms/engine/admin/materials/_search_form.html.erb +2 -2
  218. data/app/views/lcms/engine/admin/materials/import.html.erb +1 -1
  219. data/app/views/lcms/engine/admin/materials/index.html.erb +26 -22
  220. data/app/views/lcms/engine/admin/materials/new.html.erb +5 -1
  221. data/app/views/lcms/engine/admin/resource_bulk_edits/new.html.erb +2 -2
  222. data/app/views/lcms/engine/admin/resources/_fields.html.erb +4 -0
  223. data/app/views/lcms/engine/admin/resources/_form.html.erb +1 -1
  224. data/app/views/lcms/engine/admin/resources/_search_form.html.erb +2 -2
  225. data/app/views/lcms/engine/admin/resources/index.html.erb +7 -5
  226. data/app/views/lcms/engine/admin/shared/_header.html.erb +12 -12
  227. data/app/views/lcms/engine/admin/standards/_form.html.erb +3 -1
  228. data/app/views/lcms/engine/admin/standards/_search_form.html.erb +1 -1
  229. data/app/views/lcms/engine/admin/users/_form.html.erb +1 -1
  230. data/app/views/lcms/engine/admin/users/_search_form.html.erb +1 -1
  231. data/app/views/lcms/engine/admin/users/index.html.erb +6 -6
  232. data/app/views/lcms/engine/documents/gdoc/_agenda.html.erb +1 -1
  233. data/app/views/lcms/engine/documents/show.html.erb +1 -1
  234. data/app/views/lcms/engine/materials/show.html.erb +1 -1
  235. data/app/views/lcms/engine/pages/not_found.html.erb +5 -0
  236. data/app/views/lcms/engine/resources/_download.html.erb +2 -2
  237. data/app/views/lcms/engine/resources/_unit_bundles.html.erb +2 -2
  238. data/app/views/lcms/engine/resources/generic.html.erb +0 -4
  239. data/app/views/lcms/engine/resources/media.html.erb +0 -4
  240. data/app/views/lcms/engine/resources/show.html.erb +0 -2
  241. data/config/initializers/airbrake.rb +62 -10
  242. data/config/initializers/bitly.rb +1 -1
  243. data/config/initializers/carrier_wave.rb +6 -4
  244. data/config/initializers/ckeditor.rb +6 -0
  245. data/config/initializers/elasticsearch.rb +1 -1
  246. data/config/initializers/resque.rb +2 -2
  247. data/config/locales/admin/en.yml +1 -2
  248. data/config/locales/ui/en.yml +1 -0
  249. data/config/routes.rb +5 -2
  250. data/db/migrate/.keep +0 -0
  251. data/db/schema.rb +280 -312
  252. data/db/seeds.rb +0 -1
  253. data/docker-compose.ror4.yml +32 -0
  254. data/docker-compose.yml +6 -3
  255. data/docs/env-variables.md +40 -40
  256. data/docs/google-cloud-platform-setup.md +45 -17
  257. data/docs/how-to-build-and-publish.md +1 -0
  258. data/lcms-engine.gemspec +28 -20
  259. data/lib/doc_template/document.rb +3 -4
  260. data/lib/doc_template/document_toc.rb +2 -2
  261. data/lib/doc_template/objects/activity_metadata.rb +1 -1
  262. data/lib/doc_template/objects/agenda_metadata.rb +1 -1
  263. data/lib/doc_template/objects/metadata_helpers.rb +1 -1
  264. data/lib/doc_template/objects/toc_helpers.rb +4 -4
  265. data/lib/doc_template/objects/toc_metadata.rb +4 -6
  266. data/lib/doc_template/tables/base.rb +3 -2
  267. data/lib/doc_template/tags/activity_metadata_type_tag.rb +1 -1
  268. data/lib/doc_template/tags/answer_space_tag.rb +2 -2
  269. data/lib/doc_template/tags/base_tag.rb +5 -5
  270. data/lib/doc_template/tags/block_tag.rb +1 -1
  271. data/lib/doc_template/tags/columns_tag.rb +1 -1
  272. data/lib/doc_template/tags/def_tag.rb +1 -1
  273. data/lib/doc_template/tags/expand_tag.rb +1 -0
  274. data/lib/doc_template/tags/heading_tag.rb +1 -1
  275. data/lib/doc_template/tags/inset_tag.rb +2 -2
  276. data/lib/doc_template/tags/latex_tag.rb +1 -1
  277. data/lib/doc_template/tags/page_break_tag.rb +1 -1
  278. data/lib/doc_template/tags/pd_tag.rb +4 -4
  279. data/lib/doc_template/tags/section_tag.rb +2 -2
  280. data/lib/doc_template/tags/standard_tag.rb +3 -3
  281. data/lib/doc_template/tags/table_preserve_alignment_tag.rb +1 -1
  282. data/lib/doc_template/tags/table_tag.rb +1 -1
  283. data/lib/doc_template/template.rb +1 -1
  284. data/lib/doc_template.rb +9 -9
  285. data/lib/document_exporter/gdoc/base.rb +6 -3
  286. data/lib/document_exporter/pdf/base.rb +1 -1
  287. data/lib/document_exporter/pdf/document.rb +2 -2
  288. data/lib/document_exporter/pdf/material.rb +2 -2
  289. data/lib/document_exporter/pdf/student_material.rb +2 -2
  290. data/lib/document_exporter/pdf/teacher_material.rb +2 -2
  291. data/lib/document_renderer/part.rb +4 -6
  292. data/lib/elasticsearch/persistence/repository/response/results.rb +1 -1
  293. data/lib/lcms/engine/engine.rb +10 -9
  294. data/lib/lcms/engine/version.rb +1 -1
  295. data/lib/lcms/engine.rb +0 -1
  296. data/lib/lt/lcms/metadata/base_service.rb +2 -1
  297. data/lib/lt/lcms/metadata/context.rb +58 -54
  298. data/lib/lt/lcms/metadata/service.rb +6 -3
  299. data/lib/resque_job.rb +3 -6
  300. data/lib/standard_importer.rb +4 -4
  301. data/lib/tasks/cloud66.rake +8 -6
  302. data/lib/tasks/document.rake +7 -7
  303. data/lib/tasks/google.rake +29 -14
  304. data/lib/tasks/lcms/engine_tasks.rake +1 -1
  305. data/package.json +31 -9
  306. data/postcss.config.js +12 -0
  307. data/spec/controllers/admin/association_picker_controller_spec.rb +6 -8
  308. data/spec/controllers/admin/curriculums_controller_spec.rb +23 -0
  309. data/spec/controllers/admin/documents_controller_spec.rb +25 -3
  310. data/spec/controllers/admin/materials_controller_spec.rb +17 -4
  311. data/spec/controllers/admin/resource_bulk_edit_controller_spec.rb +1 -1
  312. data/spec/controllers/admin/resources_controller_spec.rb +3 -3
  313. data/spec/controllers/admin/settings_controller_spec.rb +1 -1
  314. data/spec/controllers/admin/standards_controller_spec.rb +1 -1
  315. data/spec/controllers/admin/welcome_controller_spec.rb +12 -10
  316. data/spec/controllers/resources_controller_spec.rb +3 -3
  317. data/spec/controllers/welcome_controller_spec.rb +38 -0
  318. data/spec/dummy/.env.docker +5 -0
  319. data/spec/dummy/.traceroute.yaml +0 -2
  320. data/spec/dummy/bin/webpack +18 -0
  321. data/spec/dummy/bin/webpack-dev-server +18 -0
  322. data/spec/dummy/config/application.rb +1 -1
  323. data/spec/dummy/config/environments/production.rb +1 -1
  324. data/spec/dummy/config/environments/test.rb +1 -1
  325. data/spec/dummy/config/initializers/assets.rb +6 -0
  326. data/spec/dummy/config/lcms-admin.yml +3 -7
  327. data/spec/dummy/config/puma.rb +3 -3
  328. data/spec/dummy/config/routes.rb +6 -0
  329. data/spec/dummy/db/schema.rb +5 -5
  330. data/spec/entities/grades_spec.rb +12 -0
  331. data/spec/factories/documents.rb +1 -0
  332. data/spec/factories/downloads.rb +1 -1
  333. data/spec/factories/resources.rb +2 -2
  334. data/spec/features/admin/lessons/add_lesson_spec.rb +3 -3
  335. data/spec/features/admin/materials/add_material_spec.rb +5 -3
  336. data/spec/features/admin/users_spec.rb +2 -2
  337. data/spec/forms/document_form_spec.rb +11 -1
  338. data/spec/{controllers/admin/admin_controller_spec.rb → helpers/path_helper_spec.rb} +6 -6
  339. data/spec/lib/doc_template/objects/activity_metadata_spec.rb +1 -1
  340. data/spec/lib/doc_template/objects/agenda_metadata_spec.rb +2 -0
  341. data/spec/lib/doc_template/objects/toc_metadata_spec.rb +1 -1
  342. data/spec/lib/doc_template/tables/shared_examples/remove_table.rb +1 -1
  343. data/spec/lib/doc_template/tags/page_break_tag_spec.rb +1 -1
  344. data/spec/lib/doc_template/tags/pd_tag_spec.rb +1 -1
  345. data/spec/models/document_spec.rb +1 -1
  346. data/spec/models/standard_spec.rb +2 -0
  347. data/spec/queries/lcms/engine/admin_materials_query_spec.rb +34 -0
  348. data/spec/rails_helper.rb +8 -2
  349. data/spec/services/document_build_service_spec.rb +4 -11
  350. data/spec/services/s3_service_spec.rb +31 -0
  351. data/spec/support/concerns/navigable.rb +2 -0
  352. data/spec/support/routes.rb +4 -0
  353. data/spec/support/shared_examples/content_tag.rb +4 -4
  354. data/templates/routes.rb +0 -1
  355. data/yarn.lock +3447 -2993
  356. metadata +208 -303
  357. data/app/assets/stylesheets/lcms/engine/application.scss +0 -36
  358. data/app/assets/stylesheets/lcms/engine/vendors/jquery.tagsinput.css +0 -1
  359. data/app/exceptions/components_api_error.rb +0 -4
  360. data/app/exceptions/document_error.rb +0 -4
  361. data/app/exceptions/material_error.rb +0 -4
  362. data/app/javascript/packs/admin.js +0 -14
  363. data/app/models/lcms/engine/component.rb +0 -88
  364. data/app/presenters/lcms/engine/social_media_presenter.rb +0 -83
  365. data/app/views/lcms/engine/shared/_social_sharing.html.erb +0 -22
  366. data/db/migrate/20200217160930_change_document_parts_to_polymorphic.rb +0 -36
  367. data/db/migrate/20200218144849_drop_material_parts_table.rb +0 -7
  368. data/db/migrate/20200422130652_add_reimported_at_to_documents.rb +0 -7
  369. data/db/migrate/20200429130353_drop_pages.rb +0 -13
  370. data/db/seeds/pages.seeds.rb +0 -26
  371. data/lib/document_exporter.rb +0 -6
  372. data/lib/lcms/engine/migration.rb +0 -16
  373. data/spec/models/component_spec.rb +0 -60
  374. data/vendor/assets/javascripts/jquery.tagsinput.js +0 -1
@@ -1,11 +1,11 @@
1
- import React from 'react'
2
- import PaginationBoxView from '../../paginate/PaginationBoxView'
1
+ import React from 'react';
2
+ import PaginationBoxView from '../../paginate/PaginationBoxView';
3
3
 
4
4
  // eslint-disable-next-line no-unused-vars
5
5
  function pickerWindowWrapper(WrappedComponent, path) {
6
6
  return class extends React.Component {
7
7
  constructor(props) {
8
- super(props)
8
+ super(props);
9
9
 
10
10
  this.state = {
11
11
  results: [],
@@ -14,73 +14,94 @@ function pickerWindowWrapper(WrappedComponent, path) {
14
14
  total_pages: 0,
15
15
  },
16
16
  q: null,
17
- }
17
+ };
18
18
  }
19
19
 
20
20
  componentDidMount() {
21
- this.fetch()
21
+ this.fetch();
22
22
  }
23
23
 
24
24
  fetch() {
25
25
  const data = {
26
26
  page: this.state.pagination.current_page,
27
27
  q: this.state.q,
28
- }
29
- const url = Routes[path].call(this, { ...data, ...this.state, ...this.props })
30
- $.getJSON(url).then(x => this.setState({ ...x }))
28
+ };
29
+ const url = Routes[path].call(this, {
30
+ ...data,
31
+ ...this.state,
32
+ ...this.props,
33
+ });
34
+ $.getJSON(url).then(x => this.setState({ ...x }));
31
35
  }
32
36
 
33
37
  onFilterChange(field, event) {
34
- this.setState({ [field]: event.target.value }, this.fetch)
38
+ this.setState({ [field]: event.target.value }, this.fetch);
35
39
  }
36
40
 
37
41
  pageClick(data) {
38
- const selected = data.selected
39
- this.setState({
40
- ...this.state,
41
- pagination: {
42
- ...this.state.pagination,
43
- current_page: selected + 1,
42
+ const selected = data.selected;
43
+ this.setState(
44
+ {
45
+ ...this.state,
46
+ pagination: {
47
+ ...this.state.pagination,
48
+ current_page: selected + 1,
49
+ },
44
50
  },
45
- }, this.fetch)
51
+ this.fetch
52
+ );
46
53
  }
47
54
 
48
55
  pagination() {
49
- const breakLabel = <li className="break"><a href="javascript:">...</a></li>
56
+ const breakLabel = (
57
+ <li className="break">
58
+ {/*
59
+ eslint-disable jsx-a11y/anchor-is-valid, no-script-url
60
+ */}
61
+ <a href="javascript:">...</a>
62
+ {/*
63
+ eslint-enable jsx-a11y/anchor-is-valid, no-script-url
64
+ */}
65
+ </li>
66
+ );
50
67
  return (
51
- <PaginationBoxView previousLabel={'< Previous'}
52
- nextLabel={ 'Next >' }
53
- breakLabel={ breakLabel }
54
- pageNum={ this.state.pagination.total_pages }
55
- initialSelected={ this.state.pagination.current_page - 1 }
56
- forceSelected={ this.state.pagination.current_page - 1 }
57
- marginPagesDisplayed={ 2 }
58
- pageRangeDisplayed={ 5 }
68
+ <PaginationBoxView
69
+ previousLabel={'< Previous'}
70
+ nextLabel={'Next >'}
71
+ breakLabel={breakLabel}
72
+ pageNum={this.state.pagination.total_pages}
73
+ initialSelected={this.state.pagination.current_page - 1}
74
+ forceSelected={this.state.pagination.current_page - 1}
75
+ marginPagesDisplayed={2}
76
+ pageRangeDisplayed={5}
59
77
  // eslint-disable-next-line react/jsx-no-bind
60
- clickCallback={ this.pageClick.bind(this) }
61
- containerClassName={ 'o-pagination o-page__wrap--row-nest' }
62
- itemClassName={ 'o-pagination__item' }
63
- nextClassName={ 'o-pagination__item--next' }
64
- previousClassName={ 'o-pagination__item--prev' }
65
- pagesClassName={ 'o-pagination__item--middle' }
66
- subContainerClassName={ 'o-pagination__pages' }
67
- activeClassName={ 'o-pagination__page--active' } />
68
- )
78
+ clickCallback={this.pageClick.bind(this)}
79
+ containerClassName={'o-pagination o-page__wrap--row-nest'}
80
+ itemClassName={'o-pagination__item'}
81
+ nextClassName={'o-pagination__item--next'}
82
+ previousClassName={'o-pagination__item--prev'}
83
+ pagesClassName={'o-pagination__item--middle'}
84
+ subContainerClassName={'o-pagination__pages'}
85
+ activeClassName={'o-pagination__page--active'}
86
+ />
87
+ );
69
88
  }
70
89
 
71
90
  render() {
72
91
  return (
73
92
  <div className="o-picker">
74
- <WrappedComponent { ...this.state } { ...this.props }
93
+ <WrappedComponent
94
+ {...this.state}
95
+ {...this.props}
75
96
  // eslint-disable-next-line react/jsx-no-bind
76
- onFilterChange={ this.onFilterChange.bind(this) }
97
+ onFilterChange={this.onFilterChange.bind(this)}
77
98
  // eslint-disable-next-line react/jsx-no-bind
78
- pagination={ this.pagination.bind(this) }
99
+ pagination={this.pagination.bind(this)}
79
100
  />
80
101
  </div>
81
- )
102
+ );
82
103
  }
83
- }
104
+ };
84
105
  }
85
106
 
86
- export default pickerWindowWrapper
107
+ export default pickerWindowWrapper;
@@ -1,80 +1,89 @@
1
- import React from 'react'
2
- import ReactDOM from 'react-dom'
3
- import ResourcePickerWindow from './ResourcePickerWindow'
4
- import ResourcePickerResource from './ResourcePickerResource'
5
- import PickerButton from '../picker/PickerButton'
6
- import pickerWindowWrapper from '../picker/pickerWindowWrapper'
7
- import pickerModal from '../picker/pickerModal'
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import PropTypes from 'prop-types';
4
+ import _ from 'lodash';
5
+ import ResourcePickerWindow from './ResourcePickerWindow';
6
+ import ResourcePickerResource from './ResourcePickerResource';
7
+ import PickerButton from '../picker/PickerButton';
8
+ import pickerWindowWrapper from '../picker/pickerWindowWrapper';
9
+ import pickerModal from '../picker/pickerModal';
10
+ import { Foundation } from 'foundation-sites';
11
+ import $ from 'jquery';
8
12
 
9
13
  class ResourcePicker extends React.Component {
10
14
  constructor(props) {
11
- super(props)
15
+ super(props);
12
16
 
13
- const resources = 'resources' in props ? props.resources : []
17
+ const resources = 'resources' in props ? props.resources : [];
14
18
 
15
19
  this.state = {
16
- resources: resources,
17
- }
20
+ resources: resources,
21
+ };
18
22
  }
19
23
 
20
24
  get jqmodal() {
21
- return $(this.modal)
25
+ return $(this.modal);
22
26
  }
23
27
 
24
28
  get allowMultiple() {
25
29
  if (_.isUndefined(this.props.allow_multiple) || this.props.allow_multiple === null) {
26
- return true
30
+ return true;
27
31
  }
28
- return this.props.allow_multiple
32
+ return this.props.allow_multiple;
29
33
  }
30
34
 
31
35
  componentDidMount() {
36
+ Foundation.addToJquery($);
32
37
  // eslint-disable-next-line no-undef
33
- pickerModal.call(this)
38
+ pickerModal.call(this);
34
39
  }
35
40
 
36
41
  onClickSelect() {
37
42
  // eslint-disable-next-line no-undef
38
- const pickerComponent = pickerWindowWrapper(ResourcePickerWindow, 'lcms_engine_admin_resource_picker_path')
39
- const picker = React.createElement(pickerComponent, {
40
- onSelectResource: this.selectResource.bind(this),
41
- }, null)
42
- ReactDOM.render(picker, this.modal)
43
- this.jqmodal.foundation('open')
43
+ const pickerComponent = pickerWindowWrapper(ResourcePickerWindow, 'lcms_engine_admin_resource_picker_path');
44
+ const picker = React.createElement(
45
+ pickerComponent,
46
+ {
47
+ onSelectResource: this.selectResource.bind(this),
48
+ },
49
+ null
50
+ );
51
+ ReactDOM.render(picker, this.modal);
52
+ this.jqmodal.foundation('open');
44
53
  }
45
54
 
46
55
  selectResource(resource) {
47
- this.jqmodal.foundation('close')
56
+ this.jqmodal.foundation('close');
48
57
 
49
- const newResources = this.allowMultiple ?
50
- [...this.state.resources, resource] :
51
- [resource]
58
+ const newResources = this.allowMultiple ? [...this.state.resources, resource] : [resource];
52
59
 
53
60
  this.setState({
54
61
  ...this.state,
55
62
  resources: newResources,
56
- })
63
+ });
57
64
  }
58
65
 
59
66
  removeResource(resource) {
60
67
  this.setState({
61
68
  ...this.state,
62
69
  resources: _.filter(this.state.resources, r => r.id !== resource.id),
63
- })
70
+ });
64
71
  }
65
72
 
66
73
  render() {
67
74
  const resources = this.state.resources.map(resource => {
68
- return <ResourcePickerResource
69
- key={resource.id}
70
- name={this.props.name}
71
- resource={resource}
72
- // eslint-disable-next-line react/jsx-no-bind
73
- onClickClose={() => this.removeResource(resource)}
74
- />
75
- })
75
+ return (
76
+ <ResourcePickerResource
77
+ key={resource.id}
78
+ name={this.props.name}
79
+ resource={resource}
80
+ // eslint-disable-next-line react/jsx-no-bind
81
+ onClickClose={() => this.removeResource(resource)}
82
+ />
83
+ );
84
+ });
76
85
 
77
- const input = <input type="hidden" name={this.props.name} value="" />
86
+ const input = <input type="hidden" name={this.props.name} value="" />;
78
87
 
79
88
  return (
80
89
  <PickerButton
@@ -83,10 +92,16 @@ class ResourcePicker extends React.Component {
83
92
  // eslint-disable-next-line react/jsx-no-bind
84
93
  onClick={this.onClickSelect.bind(this)}
85
94
  // eslint-disable-next-line react/jsx-no-bind
86
- onRef={m => this.modal = m}
95
+ onRef={m => (this.modal = m)}
87
96
  />
88
- )
97
+ );
89
98
  }
90
99
  }
91
100
 
92
- export default ResourcePicker
101
+ ResourcePicker.propTypes = {
102
+ name: PropTypes.string,
103
+ resources: PropTypes.array,
104
+ allow_multiple: PropTypes.bool,
105
+ };
106
+
107
+ export default ResourcePicker;
@@ -1,13 +1,24 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
1
4
  function ResourcePickerResource(props) {
2
5
  return (
3
6
  <div className="o-assocpicker-selection">
4
7
  <input type="hidden" name={props.name} value={props.resource.id} />
5
8
  <div className="o-assocpicker-title">
6
9
  {props.resource.title}
7
- <span className="o-assocpicker-close" onClick={props.onClickClose}>×</span>
10
+ <span className="o-assocpicker-close" onClick={props.onClickClose}>
11
+ ×
12
+ </span>
8
13
  </div>
9
14
  </div>
10
- )
15
+ );
11
16
  }
12
17
 
13
- export default ResourcePickerResource
18
+ ResourcePickerResource.propTypes = {
19
+ name: PropTypes.string,
20
+ resource: PropTypes.object,
21
+ onClickClose: PropTypes.func,
22
+ };
23
+
24
+ export default ResourcePickerResource;
@@ -1,20 +1,21 @@
1
- import React from 'react'
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
2
3
 
3
4
  class ResourcePickerWindow extends React.Component {
4
5
  constructor(props) {
5
- super(props)
6
+ super(props);
6
7
 
7
8
  this.typeOptions = [
8
9
  ['subject', 'subject'],
9
10
  ['grade', 'grade'],
10
11
  ['module', 'module'],
11
12
  ['unit', 'unit'],
12
- ]
13
+ ];
13
14
 
14
15
  this.subjectOptions = [
15
16
  ['ela', 'ELA'],
16
17
  ['math', 'Math'],
17
- ]
18
+ ];
18
19
 
19
20
  this.gradeOptions = [
20
21
  ['pk', 'prekindergarten'],
@@ -31,7 +32,7 @@ class ResourcePickerWindow extends React.Component {
31
32
  ['10', 'grade 10'],
32
33
  ['11', 'grade 11'],
33
34
  ['12', 'grade 12'],
34
- ]
35
+ ];
35
36
 
36
37
  const initialState = {
37
38
  pagination: {
@@ -43,45 +44,59 @@ class ResourcePickerWindow extends React.Component {
43
44
  subject: null,
44
45
  grade: null,
45
46
  q: null,
46
- }
47
+ };
47
48
 
48
- this.state = { ...initialState, ...props }
49
+ this.state = { ...initialState, ...props };
49
50
  }
50
51
 
51
52
  filterElement(title, value, type, data) {
52
53
  return (
53
- <label className="medium-3 columns">{ title }
54
- <select value={value || ''} onChange={ this.props.onFilterChange.bind(this, type) }>
54
+ <label className="medium-3 columns">
55
+ {title}
56
+ <select
57
+ value={value || ''}
58
+ /* eslint-disable react/jsx-no-bind */
59
+ onChange={this.props.onFilterChange.bind(this, type)}
60
+ >
55
61
  <option />
56
62
  {data.map(([value, title]) => (
57
- <option key={value} value={value}>{title}</option>
63
+ <option key={value} value={value}>
64
+ {title}
65
+ </option>
58
66
  ))}
59
67
  </select>
60
68
  </label>
61
- )
69
+ );
62
70
  }
63
71
 
64
72
  selectResource(resource) {
65
73
  if ('onSelectResource' in this.props) {
66
- this.props.onSelectResource(resource)
74
+ this.props.onSelectResource(resource);
67
75
  }
68
76
  }
69
77
 
70
78
  render() {
71
- const { grade, q, subject, type } = this.props
79
+ const { grade, q, subject, type } = this.props;
72
80
 
81
+ /* eslint-disable jsx-a11y/anchor-is-valid */
73
82
  return (
74
83
  <div className="o-assocpicker">
75
84
  <div className="o-page">
76
85
  <div className="o-page__module">
77
86
  <h4 className="text-center">Select resource</h4>
78
87
  <div className="row">
79
- { this.filterElement('Curriculum Type', type, 'type', this.typeOptions) }
80
- { this.filterElement('Subject', subject, 'subject', this.subjectOptions) }
81
- { this.filterElement('Grade', grade, 'grade', this.gradeOptions) }
88
+ {this.filterElement('Curriculum Type', type, 'type', this.typeOptions)}
89
+ {this.filterElement('Subject', subject, 'subject', this.subjectOptions)}
90
+ {this.filterElement('Grade', grade, 'grade', this.gradeOptions)}
82
91
 
83
- <label className="medium-3 columns">Title
84
- <input type="text" value={q || ''} onChange={ this.props.onFilterChange.bind(this, 'q') } />
92
+ <label className="medium-3 columns">
93
+ Title
94
+ <input
95
+ type="text"
96
+ value={q || ''}
97
+ /* eslint-disable react/jsx-no-bind */
98
+ onChange={this.props.onFilterChange.bind(this, 'q')}
99
+ />
85
100
  </label>
86
101
  </div>
87
102
  </div>
@@ -98,18 +113,32 @@ class ResourcePickerWindow extends React.Component {
98
113
  <tbody>
99
114
  {this.props.results.map(resource => (
100
115
  <tr key={resource.id}>
116
+ {/*
117
+ eslint-disable react/jsx-no-bind
118
+ */}
101
119
  <td onClick={this.selectResource.bind(this, resource)}>{resource.title}</td>
102
120
  </tr>
103
121
  ))}
104
122
  </tbody>
105
123
  </table>
106
124
 
107
- { this.props.pagination() }
125
+ {this.props.pagination()}
108
126
  </div>
109
127
  </div>
110
128
  </div>
111
- )
129
+ );
112
130
  }
113
131
  }
114
132
 
115
- export default ResourcePickerWindow
133
+ ResourcePickerWindow.propTypes = {
134
+ onFilterChange: PropTypes.func,
135
+ onSelectResource: PropTypes.func,
136
+ grade: PropTypes.string,
137
+ q: PropTypes.string,
138
+ subject: PropTypes.string,
139
+ type: PropTypes.string,
140
+ results: PropTypes.array,
141
+ pagination: PropTypes.func,
142
+ };
143
+
144
+ export default ResourcePickerWindow;
@@ -1,29 +1,41 @@
1
1
  // from https://github.com/AdeleD/react-paginate (converted)
2
2
 
3
- import React from 'react'
3
+ import React from 'react';
4
+ import PropTypes from 'prop-types';
4
5
 
5
6
  // eslint-disable-next-line no-unused-vars
6
7
  class PageView extends React.Component {
7
8
  render() {
8
- const linkClassName = this.props.pageLinkClassName
9
- let cssClassName = this.props.pageClassName
9
+ const linkClassName = this.props.pageLinkClassName;
10
+ let cssClassName = this.props.pageClassName;
10
11
 
11
12
  if (this.props.selected) {
12
- if (typeof(cssClassName) !== 'undefined') {
13
- cssClassName = cssClassName + ' ' + this.props.activeClassName
13
+ if (typeof cssClassName !== 'undefined') {
14
+ cssClassName = cssClassName + ' ' + this.props.activeClassName;
14
15
  } else {
15
- cssClassName = this.props.activeClassName
16
+ cssClassName = this.props.activeClassName;
16
17
  }
17
18
  }
18
19
 
20
+ /* eslint-disable jsx-a11y/anchor-is-valid */
19
21
  return (
20
22
  <li className={cssClassName}>
21
23
  <a onClick={this.props.onClick} className={linkClassName}>
22
24
  {this.props.page}
23
25
  </a>
24
26
  </li>
25
- )
27
+ );
28
+ /* eslint-enable jsx-a11y/anchor-is-valid */
26
29
  }
27
30
  }
28
31
 
29
- export default PageView
32
+ PageView.propTypes = {
33
+ pageLinkClassName: PropTypes.string,
34
+ pageClassName: PropTypes.string,
35
+ selected: PropTypes.bool,
36
+ activeClassName: PropTypes.string,
37
+ onClick: PropTypes.func.isRequired,
38
+ page: PropTypes.number,
39
+ };
40
+
41
+ export default PageView;