demo_mode 2.3.0 → 3.0.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/app/controllers/demo_mode/sessions_controller.rb +3 -2
- data/app/jobs/demo_mode/account_generation_job.rb +4 -2
- data/app/models/demo_mode/session.rb +15 -0
- data/app/views/demo_mode/sessions/show.html.erb +5 -1
- data/db/migrate/20250210222933_add_demo_mode_sessions_status.rb +13 -0
- data/lib/demo_mode/version.rb +1 -1
- data/public/demo_mode/assets/demo_mode.css +4 -0
- data/public/demo_mode/assets/demo_mode.js +50 -37
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68c310d6d0797c6f17fb85f41ec11f72305619323bf7bf2174d6b6a44c2954f4
|
4
|
+
data.tar.gz: fd5fe9b737d929072e50576ffedfe93d5e516414adb384a4e6d2b4cdc856868a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a235b3dd997af98b44b1947fc3a8832f33793ef0600a027a935cf8cfc0d6c40f9232b2fe969dc146845e319ae9c150001d33308568e6876b9667a4968f8279d1
|
7
|
+
data.tar.gz: f848277ff5fa0a11e27e2c6f0d701069a17b818eceba5e0d86a7e9ce12c5592dfa0b7fe86da1248f07f07122824ccb84a2e3090cb6d0909fbb702f65824a0acf
|
@@ -50,11 +50,12 @@ module DemoMode
|
|
50
50
|
|
51
51
|
def render_signinable_json
|
52
52
|
if @session.signinable.blank?
|
53
|
-
render json: { id: @session.id, processing:
|
53
|
+
render json: { id: @session.id, processing: @session.processing?, status: @session.status }
|
54
54
|
else
|
55
55
|
render json: {
|
56
56
|
id: @session.id,
|
57
|
-
processing:
|
57
|
+
processing: @session.processing?,
|
58
|
+
status: @session.status,
|
58
59
|
username: @session.signinable_username,
|
59
60
|
password: @session.signinable_password,
|
60
61
|
}
|
@@ -8,9 +8,11 @@ module DemoMode
|
|
8
8
|
raise "Unknown persona: #{session.persona_name}" if persona.blank?
|
9
9
|
|
10
10
|
signinable = persona.generate!(variant: session.variant, password: session.signinable_password, options: options)
|
11
|
-
session.update!(signinable: signinable)
|
11
|
+
session.update!(signinable: signinable, status: 'successful')
|
12
12
|
end
|
13
|
-
|
13
|
+
rescue StandardError => e
|
14
|
+
session.update!(status: 'failed')
|
15
|
+
raise e
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -4,8 +4,17 @@ module DemoMode
|
|
4
4
|
class Session < ActiveRecord::Base
|
5
5
|
attribute :variant, default: :default
|
6
6
|
|
7
|
+
if ActiveRecord.gem_version >= Gem::Version.new('7.2')
|
8
|
+
enum :status, { processing: 'processing', successful: 'successful', failed: 'failed' }, default: 'processing'
|
9
|
+
else
|
10
|
+
attribute :status, default: :processing
|
11
|
+
enum status: { processing: 'processing', successful: 'successful', failed: 'failed' }
|
12
|
+
end
|
13
|
+
|
7
14
|
validates :persona_name, :variant, presence: true
|
8
15
|
validates :persona, presence: { message: :required }, on: :create, if: :persona_name?
|
16
|
+
validate :successful_status_requires_signinable
|
17
|
+
|
9
18
|
belongs_to :signinable, polymorphic: true, optional: true
|
10
19
|
|
11
20
|
before_create :set_password!
|
@@ -44,5 +53,11 @@ module DemoMode
|
|
44
53
|
def set_password!
|
45
54
|
self.signinable_password ||= DemoMode.current_password
|
46
55
|
end
|
56
|
+
|
57
|
+
def successful_status_requires_signinable
|
58
|
+
if status == 'successful' && signinable.blank?
|
59
|
+
errors.add(:status, 'cannot be successful if signinable is not present')
|
60
|
+
end
|
61
|
+
end
|
47
62
|
end
|
48
63
|
end
|
@@ -17,10 +17,14 @@
|
|
17
17
|
</article>
|
18
18
|
<% else %>
|
19
19
|
<article class="middle center" data-polling-refresh-url='<%= session_path(@session, format: :json) %>'>
|
20
|
-
<figure>
|
20
|
+
<figure id="LoadingMessage" class="<%= 'hidden' if @session.failed? %>">
|
21
21
|
<%= instance_eval(&DemoMode.loader) %>
|
22
22
|
<h4><span id="DemoTypedText"></span></h4>
|
23
23
|
</figure>
|
24
|
+
<div id="ErrorMessage" class="<%= 'hidden' unless @session.failed? %>">
|
25
|
+
<div>Unable to generate persona.</div>
|
26
|
+
<%= link_to "Go back to persona selection", new_session_path, aria: { label: 'Homepage' } %>
|
27
|
+
</div>
|
24
28
|
|
25
29
|
<script type="text/javascript">
|
26
30
|
new Typed('#DemoTypedText', {
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddDemoModeSessionsStatus < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
add_column :demo_mode_sessions, :status, :string, null: false, default: 'processing'
|
6
|
+
|
7
|
+
reversible do |dir|
|
8
|
+
dir.up do
|
9
|
+
execute "UPDATE demo_mode_sessions SET status = 'successful'"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/demo_mode/version.rb
CHANGED
@@ -1,15 +1,24 @@
|
|
1
|
-
(function(document, performance, location) {
|
1
|
+
(function (document, performance, location) {
|
2
2
|
function* getJSON(url) {
|
3
|
-
while(true) {
|
3
|
+
while (true) {
|
4
|
+
yield fetch(url).then((resp) => resp.json());
|
5
|
+
}
|
4
6
|
}
|
5
7
|
|
6
8
|
function pollURL(url, minInterval, success, func) {
|
7
9
|
const then = performance.now();
|
8
|
-
if(!minInterval) {
|
9
|
-
|
10
|
+
if (!minInterval) {
|
11
|
+
minInterval = 1000;
|
12
|
+
}
|
13
|
+
if (!func) {
|
14
|
+
func = getJSON(url);
|
15
|
+
}
|
10
16
|
|
11
17
|
func.next().value.then((resp) => {
|
12
|
-
if(resp.
|
18
|
+
if (resp.status === 'failed') {
|
19
|
+
document.querySelector("#LoadingMessage").classList.add("hidden");
|
20
|
+
document.querySelector("#ErrorMessage").classList.remove("hidden");
|
21
|
+
} else if (resp.status === 'processing') {
|
13
22
|
setTimeout(
|
14
23
|
() => pollURL(url, minInterval, success, func),
|
15
24
|
Math.max(0, minInterval - (performance.now() - then))
|
@@ -20,50 +29,54 @@
|
|
20
29
|
});
|
21
30
|
}
|
22
31
|
|
23
|
-
document.addEventListener(
|
24
|
-
[...document.querySelectorAll(
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
document.addEventListener("DOMContentLoaded", (event) => {
|
33
|
+
[...document.querySelectorAll("[data-polling-refresh-url]")].forEach(
|
34
|
+
(elem) => {
|
35
|
+
pollURL(
|
36
|
+
elem.getAttribute("data-polling-refresh-url"),
|
37
|
+
elem.getAttribute("data-polling-refresh-interval") * 1000,
|
38
|
+
() => location.reload()
|
39
|
+
);
|
40
|
+
}
|
41
|
+
);
|
31
42
|
});
|
32
|
-
}(document, performance, location)
|
43
|
+
})(document, performance, location);
|
33
44
|
|
34
|
-
(function() {
|
35
|
-
var TableFilter = (function() {
|
45
|
+
(function () {
|
46
|
+
var TableFilter = (function () {
|
36
47
|
var input;
|
37
48
|
var inputValue;
|
38
49
|
|
39
50
|
function onInputEvent(e) {
|
40
51
|
input = e.target;
|
41
|
-
inputValue = input.value.toLowerCase().replace(/[^0-9a-zA-Z ]/g,
|
42
|
-
updateTable()
|
43
|
-
updateHistory()
|
52
|
+
inputValue = input.value.toLowerCase().replace(/[^0-9a-zA-Z ]/g, "");
|
53
|
+
updateTable();
|
54
|
+
updateHistory();
|
44
55
|
}
|
45
56
|
|
46
57
|
function updateTable() {
|
47
58
|
var table = document.querySelector(`.${input.dataset.table}`);
|
48
59
|
if (table) {
|
49
|
-
Array.prototype.forEach.call(table.tBodies, function(tbody) {
|
60
|
+
Array.prototype.forEach.call(table.tBodies, function (tbody) {
|
50
61
|
Array.prototype.forEach.call(tbody.rows, filter);
|
51
62
|
});
|
52
63
|
} else {
|
53
|
-
alert(
|
64
|
+
alert("TableFilter cannot find its table");
|
54
65
|
}
|
55
66
|
}
|
56
67
|
|
57
68
|
function updateHistory() {
|
58
|
-
var searchParams = new URLSearchParams(window.location.search)
|
69
|
+
var searchParams = new URLSearchParams(window.location.search);
|
59
70
|
searchParams.set("search", inputValue);
|
60
|
-
var newRelativePathQuery =
|
61
|
-
|
71
|
+
var newRelativePathQuery =
|
72
|
+
window.location.pathname + "?" + searchParams.toString();
|
73
|
+
history.pushState(null, "", newRelativePathQuery);
|
62
74
|
}
|
63
75
|
|
64
76
|
function filter(row) {
|
65
|
-
var text = row.textContent.toLowerCase().replace(/[^0-9a-zA-Z ]/g,
|
66
|
-
row.style.display =
|
77
|
+
var text = row.textContent.toLowerCase().replace(/[^0-9a-zA-Z ]/g, "");
|
78
|
+
row.style.display =
|
79
|
+
text.indexOf(inputValue) === -1 ? "none" : "table-row";
|
67
80
|
}
|
68
81
|
|
69
82
|
function debounce(func, threshold) {
|
@@ -76,7 +89,7 @@
|
|
76
89
|
function delayed() {
|
77
90
|
func.apply(obj, args);
|
78
91
|
timeout = null;
|
79
|
-
}
|
92
|
+
}
|
80
93
|
|
81
94
|
if (timeout) {
|
82
95
|
clearTimeout(timeout);
|
@@ -86,32 +99,32 @@
|
|
86
99
|
}
|
87
100
|
|
88
101
|
return {
|
89
|
-
init: function() {
|
90
|
-
var input = document.querySelector(
|
102
|
+
init: function () {
|
103
|
+
var input = document.querySelector("input[data-behavior=table-filter]");
|
91
104
|
if (!input) return;
|
92
105
|
|
93
106
|
input.oninput = debounce(onInputEvent, 250);
|
94
107
|
var urlParams = new URLSearchParams(window.location.search);
|
95
|
-
var search = urlParams.get(
|
108
|
+
var search = urlParams.get("search");
|
96
109
|
if (search) {
|
97
|
-
input.value = search
|
98
|
-
input.dispatchEvent(new InputEvent(
|
110
|
+
input.value = search;
|
111
|
+
input.dispatchEvent(new InputEvent("input", { data: search }));
|
99
112
|
}
|
100
113
|
|
101
|
-
window.addEventListener(
|
114
|
+
window.addEventListener("popstate", (event) => {
|
102
115
|
var urlParams = new URLSearchParams(window.location.search);
|
103
|
-
var search = urlParams.get(
|
116
|
+
var search = urlParams.get("search");
|
104
117
|
if (search) {
|
105
118
|
input.value = search;
|
106
119
|
inputValue = search;
|
107
|
-
updateTable()
|
120
|
+
updateTable();
|
108
121
|
}
|
109
122
|
});
|
110
|
-
}
|
123
|
+
},
|
111
124
|
};
|
112
125
|
})();
|
113
126
|
|
114
|
-
document.addEventListener(
|
127
|
+
document.addEventListener("DOMContentLoaded", (event) => {
|
115
128
|
TableFilter.init();
|
116
129
|
});
|
117
130
|
})();
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: demo_mode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Griffith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-02-
|
11
|
+
date: 2025-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -322,6 +322,7 @@ files:
|
|
322
322
|
- db/migrate/20190503143021_add_demo_mode_sessions.rb
|
323
323
|
- db/migrate/20201111000000_add_demo_mode_sessions_variant.rb
|
324
324
|
- db/migrate/20210505000000_add_demo_mode_sessions_password.rb
|
325
|
+
- db/migrate/20250210222933_add_demo_mode_sessions_status.rb
|
325
326
|
- lib/demo_mode.rb
|
326
327
|
- lib/demo_mode/clever_sequence.rb
|
327
328
|
- lib/demo_mode/cli.rb
|