Skip to content

Commit 220abc3

Browse files
committed
hyper-store hyper-component hyper-operation and hyper-model specs passing
1 parent 09ac3a0 commit 220abc3

File tree

13 files changed

+1479
-2
lines changed

13 files changed

+1479
-2
lines changed

change-log.md

Whitespace-only changes.

docs/tutorial/todo-part-2.md

Lines changed: 933 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
module Components
2+
module Drafts
3+
module Pro
4+
module Sidebar
5+
class PaperItem < HyperComponent
6+
param :paper, type: Paper
7+
param :job
8+
param :index
9+
10+
include Hyperstack::Component::Tracker[:components]
11+
12+
after_mount do
13+
DOM[dom_node].tooltip({ delay: { show: 750, hide: 0 } }.to_n) if conflicts
14+
end
15+
16+
after_update do
17+
DOM[dom_node].tooltip(:destroy)
18+
DOM[dom_node].tooltip({ delay: { show: 750, hide: 0 } }.to_n) if conflicts
19+
end
20+
21+
def conflicts
22+
return false if @Job.calculate_conflict_triggers.loading?
23+
triggers = @Job.calculate_conflict_triggers[:paper_ids]
24+
triggers.any? && triggers[@Paper.id.to_s]
25+
end
26+
27+
def selected?
28+
@Job.paper == @Paper
29+
end
30+
31+
def class_names
32+
classes = ['paper-list-item list-group-item']
33+
classes << :active if selected?
34+
classes << :disabled if conflicts
35+
classes << @Index.even? ? :even : :odd
36+
end
37+
38+
39+
def size_conflict_message
40+
"#{@Paper.name} has a maximum size of "\
41+
"#{@Paper.portrait_width_in_local_units} "\
42+
"x #{@Paper.portrait_height_in_local_units}"
43+
end
44+
45+
def conflict_message
46+
return '' unless conflicts
47+
return conflicts unless conflicts == 'size'
48+
size_conflict_message
49+
end
50+
51+
def select_paper
52+
return if conflicts
53+
DOM['.paper-list-item'].remove_class('active')
54+
DOM["#paper_#{@Paper.id}"].add_class('active')
55+
after(0) do # maybe able to bulk_update method
56+
@Job.paper_selected = true
57+
@Job.paper_id = @Paper.id
58+
@Job.paper = @Paper
59+
Drafts::App.update_job_calcs
60+
end
61+
end
62+
63+
def detail_row(detail)
64+
TH { detail.split(': ')[0] }
65+
TD { detail.split(': ')[1] }
66+
end
67+
68+
render do
69+
LI(id: "paper_#{@Paper.id}", title: conflict_message,
70+
class: class_names,
71+
data: { toggle: :tooltip, placement: 'auto left', container: :body }) do
72+
DIV(class: 'row paper-row') do
73+
DIV(class: 'col-sm-8 text-left') do
74+
SPAN(class: 'medium-weight') { @Paper.name }
75+
end
76+
DIV(class: 'col-sm-4') do
77+
unless @Paper.details.blank?
78+
SPAN(class: "paper-details-button #{'expanded' if @expanded}") do
79+
SPAN { "#{'Hide' if @expanded} Details" }
80+
I(class: 'material-icons', style: { verticalAlign: 'middle' }) do
81+
"expand_#{@expanded ? :less : :more}"
82+
end
83+
end.on(:click) do |e|
84+
e.prevent_default
85+
e.stop_propagation
86+
toggle :expanded
87+
end
88+
end
89+
end
90+
if @expanded && !@Paper.details.blank?
91+
DIV(class: 'col-sm-12') do
92+
TABLE(class: 'table paper-details-list') do
93+
TBODY do
94+
@Paper.details.each do |detail|
95+
TR { detail_row(detail) }
96+
end
97+
@Paper.description.gsub(%r{<[/]*\w+>}, '')
98+
.delete("\r").split("\n").reject(&:blank?).each do |detail|
99+
TR { detail_row(detail) }
100+
end
101+
end
102+
end
103+
end
104+
end
105+
end
106+
end.on(:click) { select_paper }
107+
end
108+
end
109+
end
110+
end
111+
end
112+
end
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
module Components
2+
module Drafts
3+
module Pro
4+
module Sidebar
5+
class PaperItem < React::Component::Base
6+
param :paper, type: Paper
7+
param :job
8+
param :index
9+
10+
define_state expanded: false
11+
12+
before_mount { self.class.components << self }
13+
14+
after_mount do
15+
Element[dom_node].tooltip({ delay: { show: 750, hide: 0 } }.to_n) if conflicts
16+
end
17+
18+
after_update do
19+
Element[dom_node].tooltip(:destroy)
20+
Element[dom_node].tooltip({ delay: { show: 750, hide: 0 } }.to_n) if conflicts
21+
end
22+
23+
before_unmount { self.class.components.delete(self) }
24+
25+
def conflicts
26+
return false if params.job.calculate_conflict_triggers.loading?
27+
triggers = params.job.calculate_conflict_triggers[:paper_ids]
28+
triggers.any? && triggers[params.paper.id.to_s]
29+
end
30+
31+
def selected?
32+
params.job.paper == params.paper
33+
end
34+
35+
def class_names
36+
classes = ['paper-list-item list-group-item']
37+
classes << :active if selected?
38+
classes << :disabled if conflicts
39+
classes << params.index.even? ? :even : :odd
40+
classes.join(' ') # TODO: once upgraded to hyperloop 0.99 or better remove this line
41+
end
42+
43+
def size_conflict_message
44+
"#{params.paper.name} has a maximum size of "\
45+
"#{params.paper.portrait_width_in_local_units} "\
46+
"x #{params.paper.portrait_height_in_local_units}"
47+
end
48+
49+
def conflict_message
50+
return '' unless conflicts
51+
return conflicts unless conflicts == 'size'
52+
size_conflict_message
53+
end
54+
55+
def select_paper
56+
return if conflicts
57+
Element['.paper-list-item'].remove_class('active')
58+
Element["#paper_#{params.paper.id}"].add_class('active')
59+
after(0) do
60+
params.job.paper_selected = true
61+
params.job.paper_id = params.paper.id
62+
params.job.paper = params.paper
63+
Drafts::App.update_job_calcs
64+
end
65+
end
66+
67+
def detail_row(detail)
68+
TH { detail.split(': ')[0] }
69+
TD { detail.split(': ')[1] }
70+
end
71+
72+
render do
73+
LI(id: "paper_#{params.paper.id}", title: conflict_message,
74+
class: class_names,
75+
data: { toggle: :tooltip, placement: 'auto left', container: :body }) do
76+
DIV(class: 'row paper-row') do
77+
DIV(class: 'col-sm-8 text-left') do
78+
SPAN(class: 'medium-weight') { params.paper.name }
79+
end
80+
DIV(class: 'col-sm-4') do
81+
unless params.paper.details.blank?
82+
SPAN(class: "paper-details-button #{'expanded' if state.expanded}") do
83+
SPAN { "#{'Hide' if state.expanded} Details" }
84+
I(class: 'material-icons', style: { verticalAlign: 'middle' }) do
85+
"expand_#{state.expanded ? :less : :more}"
86+
end
87+
end.on(:click) do |e|
88+
e.prevent_default
89+
e.stop_propagation
90+
state.expanded! !state.expanded
91+
end
92+
end
93+
end
94+
if state.expanded && !params.paper.details.blank?
95+
DIV(class: 'col-sm-12') do
96+
TABLE(class: 'table paper-details-list') do
97+
TBODY do
98+
params.paper.details.each do |detail|
99+
TR { detail_row(detail) }
100+
end
101+
params.paper.description.gsub(%r{<[/]*\w+>}, '')
102+
.delete("\r").split("\n").reject(&:blank?).each do |detail|
103+
TR { detail_row(detail) }
104+
end
105+
end
106+
end
107+
end
108+
end
109+
end
110+
end.on(:click) { select_paper }
111+
end
112+
end
113+
end
114+
end
115+
end
116+
end
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module Hyperstack
2+
module Component
3+
module WhileLoading
4+
def __hyperstack_component_rescue_wrapper(child)
5+
Hyperstack::Internal::Component::WhileLoadingWrapper(child: self, children_elements: child)
6+
end
7+
8+
def resources_loading?
9+
@__hyperstack_while_loading_waiting_on_resources
10+
end
11+
12+
def resources_loaded?
13+
!@__hyperstack_while_loading_waiting_on_resources
14+
end
15+
16+
if Hyperstack::Component::IsomorphicHelpers.on_opal_client?
17+
%x{
18+
function onError(event) {
19+
if (event.message.startsWith('Uncaught NotQuiet: ')) event.preventDefault();
20+
}
21+
22+
window.addEventListener('error', onError);
23+
}
24+
end
25+
end
26+
end
27+
end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
module Hyperstack
2+
module Internal
3+
module Component
4+
class RescueMetaWrapper
5+
include Hyperstack::Component
6+
7+
param :children_elements
8+
9+
render do
10+
@ChildrenElements.call
11+
end
12+
end
13+
14+
class RescueWrapper
15+
class << self
16+
attr_accessor :after_error_args
17+
end
18+
19+
include Hyperstack::Component
20+
21+
param :child
22+
param :children_elements
23+
24+
render do
25+
RescueMetaWrapper(children_elements: @ChildrenElements)
26+
end
27+
28+
after_error do |error, info|
29+
args = RescueWrapper.after_error_args || [error, info]
30+
found, * = @Child.run_callback(:__hyperstack_component_rescue_hook, found, *args) { |a| a }
31+
unless found
32+
RescueWrapper.after_error_args = args
33+
raise error
34+
end
35+
@Child.force_update!
36+
end
37+
end
38+
end
39+
end
40+
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module Hyperstack
2+
module Internal
3+
module Component
4+
class WhileLoadingWrapper < RescueWrapper
5+
render do
6+
if @waiting_on_resources && !quiet?
7+
RenderingContext.raise_if_not_quiet = false
8+
else
9+
@waiting_on_resources = false
10+
@Child.instance_eval do
11+
mutate if @__hyperstack_while_loading_waiting_on_resources
12+
@__hyperstack_while_loading_waiting_on_resources = false
13+
end
14+
RenderingContext.raise_if_not_quiet = true
15+
end
16+
RescueMetaWrapper(children_elements: @ChildrenElements)
17+
end
18+
19+
before_mount do
20+
wrapper = self
21+
@Child.class.rescues RenderingContext::NotQuiet do
22+
wrapper.instance_variable_set(:@waiting_on_resources, true)
23+
@__hyperstack_while_loading_waiting_on_resources = true
24+
end
25+
end
26+
end
27+
end
28+
end
29+
end
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
require 'spec_helper'
2+
3+
describe 'misc client helpers', js: true do
4+
context 'pluralize' do
5+
before(:each) do
6+
on_client do
7+
class TestComponent < Hyperloop::Component
8+
param :count
9+
render(DIV) do
10+
DIV { pluralize(@Count, "criterium") }
11+
DIV { pluralize(@Count, "item", "itemz") }
12+
end
13+
end
14+
end
15+
end
16+
it "1 will be singlular" do
17+
mount 'TestComponent', count: 1
18+
expect(page).to have_content("1 criterium")
19+
expect(page).to have_content("1 item")
20+
end
21+
it "2 will be plural" do
22+
mount 'TestComponent', count: 2
23+
expect(page).to have_content("2 criteria")
24+
expect(page).to have_content("2 itemz")
25+
end
26+
end
27+
end

0 commit comments

Comments
 (0)