forked from discourse/discourse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwizard.rb
138 lines (110 loc) · 3.08 KB
/
wizard.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# frozen_string_literal: true
class Wizard
attr_reader :steps, :user
attr_accessor :max_topics_to_require_completion
@@excluded_steps = []
def initialize(user)
@steps = []
@user = user
@first_step = nil
@max_topics_to_require_completion = 15
end
def create_step(step_name)
Step.new(step_name)
end
def append_step(step, after: nil)
return if @@excluded_steps.include?(step)
step = create_step(step) if step.is_a?(String)
yield step if block_given?
if after
before_step = @steps.detect { |s| s.id == after }
if before_step
step.previous = before_step
step.index = before_step.index + 1
if before_step.next
step.next = before_step.next
before_step.next.previous = step
end
before_step.next = step
@steps.insert(before_step.index + 1, step)
step.index += 1 while (step = step.next)
return
end
end
last_step = @steps.last
@steps << step
# If it's the first step
if @steps.size == 1
@first_step = step
step.index = 0
elsif last_step.present?
last_step.next = step
step.previous = last_step
step.index = last_step.index + 1
end
end
def remove_step(step_id)
i = @steps.index { |step| step.id == step_id }
return if i.nil?
step = @steps.delete_at(i)
step.previous.next = step.next if step.previous
while step = step.next
step.index -= 1
if step.index == 0
step.previous = nil
@first_step = step
else
step.previous = @steps[step.index - 1]
end
end
end
def self.exclude_step(step)
@@excluded_steps << step
end
def steps_with_fields
@steps_with_fields ||= @steps.select(&:has_fields?)
end
def start
completed =
UserHistory
.where(action: UserHistory.actions[:wizard_step], context: steps_with_fields.map(&:id))
.uniq
.pluck(:context)
# First uncompleted step
steps_with_fields.each { |s| return s unless completed.include?(s.id) }
@first_step
end
def create_updater(step_id, fields)
step = @steps.find { |s| s.id == step_id.dasherize }
Wizard::StepUpdater.new(@user, step, fields)
end
def completed?
completed_steps?(steps_with_fields.map(&:id))
end
def completed_steps?(steps)
steps = [steps].flatten.uniq
completed =
UserHistory
.where(action: UserHistory.actions[:wizard_step], context: steps)
.distinct
.order(:context)
.pluck(:context)
steps.sort == completed
end
def requires_completion?
return false unless SiteSetting.wizard_enabled?
return false if SiteSetting.bypass_wizard_check?
if Topic.limit(@max_topics_to_require_completion + 1).count > @max_topics_to_require_completion
SiteSetting.bypass_wizard_check = true
return false
end
if @user&.id && User.first_login_admin_id == @user.id
!Wizard::Builder.new(@user).build.completed?
else
false
end
end
def self.user_requires_completion?(user)
self.new(user).requires_completion?
end
end