plugin.rb 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. # name: discourse-custom-wizard
  2. # about: Create custom wizards
  3. # version: 0.1
  4. # authors: Angus McLeod
  5. register_asset 'stylesheets/wizard_custom_admin.scss'
  6. config = Rails.application.config
  7. config.assets.paths << Rails.root.join("plugins", "discourse-custom-wizard", "assets", "javascripts")
  8. config.assets.paths << Rails.root.join("plugins", "discourse-custom-wizard", "assets", "stylesheets", "wizard")
  9. after_initialize do
  10. require_dependency "application_controller"
  11. module ::CustomWizard
  12. class Engine < ::Rails::Engine
  13. engine_name "custom_wizard"
  14. isolate_namespace CustomWizard
  15. end
  16. end
  17. load File.expand_path('../lib/builder.rb', __FILE__)
  18. load File.expand_path('../lib/field.rb', __FILE__)
  19. load File.expand_path('../lib/wizard.rb', __FILE__)
  20. load File.expand_path('../app/controllers/wizard.rb', __FILE__)
  21. load File.expand_path('../app/controllers/steps.rb', __FILE__)
  22. load File.expand_path('../app/controllers/admin.rb', __FILE__)
  23. CustomWizard::Engine.routes.draw do
  24. get ':wizard_id' => 'wizard#index'
  25. get ':wizard_id/steps' => 'steps#index'
  26. get ':wizard_id/steps/:step_id' => 'wizard#index'
  27. put ':wizard_id/steps/:step_id' => 'steps#update'
  28. end
  29. require_dependency 'admin_constraint'
  30. Discourse::Application.routes.append do
  31. mount ::CustomWizard::Engine, at: 'w'
  32. scope module: 'custom_wizard', constraints: AdminConstraint.new do
  33. get 'admin/wizards' => 'admin#index'
  34. get 'admin/wizards/field-types' => 'admin#field_types'
  35. get 'admin/wizards/custom' => 'admin#index'
  36. get 'admin/wizards/custom/new' => 'admin#index'
  37. get 'admin/wizards/custom/all' => 'admin#custom_wizards'
  38. get 'admin/wizards/custom/:wizard_id' => 'admin#find_wizard'
  39. put 'admin/wizards/custom/save' => 'admin#save'
  40. delete 'admin/wizards/custom/remove' => 'admin#remove'
  41. get 'admin/wizards/submissions' => 'admin#index'
  42. get 'admin/wizards/submissions/all' => 'admin#submissions'
  43. get 'admin/wizards/submissions/:wizard_id' => 'admin#find_submissions'
  44. end
  45. end
  46. require_dependency 'wizard'
  47. require_dependency 'wizard/step'
  48. require_dependency 'wizard/step_updater'
  49. require_dependency 'wizard/field'
  50. ::Wizard.class_eval do
  51. attr_accessor :id, :background, :save_submissions, :multiple_submissions
  52. def initialize(user, attrs = {})
  53. @steps = []
  54. @user = user
  55. @first_step = nil
  56. @max_topics_to_require_completion = 15
  57. @id = attrs[:id] if attrs[:id]
  58. @save_submissions = attrs[:save_submissions] if attrs[:save_submissions]
  59. @multiple_submissions = attrs[:multiple_submissions] if attrs[:multiple_submissions]
  60. @background = attrs[:background] if attrs[:background]
  61. @custom = attrs[:custom] if attrs[:custom]
  62. end
  63. def completed?
  64. completed_steps?(@steps.map(&:id))
  65. end
  66. def completed_steps?(steps)
  67. steps = [steps].flatten.uniq
  68. completed = UserHistory.where(
  69. acting_user_id: @user.id,
  70. action: UserHistory.actions[:wizard_step]
  71. ).where(context: steps)
  72. .distinct.order(:context).pluck(:context)
  73. steps.sort == completed
  74. end
  75. def start
  76. completed = UserHistory.where(
  77. acting_user_id: @user.id,
  78. action: UserHistory.actions[:wizard_step]
  79. ).where(context: @steps.map(&:id))
  80. .uniq.pluck(:context)
  81. # First uncompleted step
  82. steps = @custom ? @steps : steps_with_fields
  83. steps.each do |s|
  84. return s unless completed.include?(s.id)
  85. end
  86. @first_step
  87. end
  88. end
  89. ::Wizard::Field.class_eval do
  90. attr_reader :label, :description, :key, :min_length
  91. def initialize(attrs)
  92. attrs = attrs || {}
  93. @id = attrs[:id]
  94. @type = attrs[:type]
  95. @required = !!attrs[:required]
  96. @label = attrs[:label]
  97. @description = attrs[:description]
  98. @key = attrs[:key]
  99. @min_length = attrs[:min_length]
  100. @value = attrs[:value]
  101. @choices = []
  102. end
  103. end
  104. class ::Wizard::Step
  105. attr_accessor :title, :description, :key
  106. end
  107. class ::Wizard::StepUpdater
  108. attr_accessor :result, :step
  109. end
  110. ::WizardSerializer.class_eval do
  111. attributes :id, :background, :completed
  112. def id
  113. object.id
  114. end
  115. def background
  116. object.background
  117. end
  118. def completed
  119. object.completed?
  120. end
  121. def include_completed?
  122. object.completed? && !object.multiple_submissions && !scope.current_user.admin?
  123. end
  124. def include_start?
  125. object.start && include_steps?
  126. end
  127. def include_steps?
  128. !include_completed?
  129. end
  130. end
  131. ::WizardStepSerializer.class_eval do
  132. def title
  133. return object.title if object.title
  134. I18n.t("#{object.key || i18n_key}.title", default: '')
  135. end
  136. def description
  137. return object.description if object.description
  138. I18n.t("#{object.key || i18n_key}.description", default: '')
  139. end
  140. end
  141. ::WizardFieldSerializer.class_eval do
  142. def label
  143. return object.label if object.label
  144. I18n.t("#{object.key || i18n_key}.label", default: '')
  145. end
  146. def description
  147. return object.description if object.description
  148. I18n.t("#{object.key || i18n_key}.description", default: '')
  149. end
  150. def placeholder
  151. I18n.t("#{object.key || i18n_key}.placeholder", default: '')
  152. end
  153. end
  154. end