You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whimsical.apache.org by ru...@apache.org on 2017/09/17 13:40:07 UTC
[whimsy] branch agenda_on_vue updated: First pass conversion
React.js => Vue.js
This is an automated email from the ASF dual-hosted git repository.
rubys pushed a commit to branch agenda_on_vue
in repository https://gitbox.apache.org/repos/asf/whimsy.git
The following commit(s) were added to refs/heads/agenda_on_vue by this push:
new 83afcf2 First pass conversion React.js => Vue.js
83afcf2 is described below
commit 83afcf2b1e29e55a7b03334d4110aa1c9fade62e
Author: Sam Ruby <ru...@intertwingly.net>
AuthorDate: Sun Sep 17 09:39:22 2017 -0400
First pass conversion React.js => Vue.js
Note: Tests are NOT passing at this time, and won't be for a while
---
www/board/agenda/Gemfile | 2 +-
www/board/agenda/README.md | 54 +++++++++----------
www/board/agenda/main.rb | 2 +-
www/board/agenda/package.json | 3 +-
www/board/agenda/views/app.js.rb | 3 ++
www/board/agenda/views/buttons/add-comment.js.rb | 2 +-
www/board/agenda/views/buttons/add-minutes.js.rb | 2 +-
www/board/agenda/views/buttons/approve.js.rb | 2 +-
www/board/agenda/views/buttons/attend.js.rb | 2 +-
www/board/agenda/views/buttons/commit.js.rb | 2 +-
www/board/agenda/views/buttons/draft-minutes.js.rb | 2 +-
www/board/agenda/views/buttons/email.js.rb | 2 +-
www/board/agenda/views/buttons/markseen.js.rb | 2 +-
www/board/agenda/views/buttons/message.js.rb | 2 +-
www/board/agenda/views/buttons/post-actions.js.rb | 2 +-
www/board/agenda/views/buttons/post.js.rb | 11 ++--
.../agenda/views/buttons/publish-minutes.js.rb | 2 +-
www/board/agenda/views/buttons/refresh.js.rb | 2 +-
www/board/agenda/views/buttons/reminders.js.rb | 4 +-
www/board/agenda/views/buttons/showseen.js.rb | 2 +-
www/board/agenda/views/buttons/timestamp.js.rb | 2 +-
www/board/agenda/views/buttons/vote.js.rb | 2 +-
.../agenda/views/elements/additional-info.js.rb | 2 +-
www/board/agenda/views/elements/info.js.rb | 2 +-
www/board/agenda/views/elements/link.js.rb | 37 ++++++-------
www/board/agenda/views/elements/modal-dialog.js.rb | 63 ++++++++++------------
www/board/agenda/views/elements/pns.rb | 2 +-
www/board/agenda/views/elements/text.js.rb | 16 +++---
www/board/agenda/views/keyboard.js.rb | 8 +--
www/board/agenda/views/layout/footer.js.rb | 6 +--
www/board/agenda/views/layout/header.js.rb | 2 +-
www/board/agenda/views/layout/main.js.rb | 24 +++++----
www/board/agenda/views/pages/action-items.js.rb | 11 ++--
www/board/agenda/views/pages/adjournment.js.rb | 8 +--
www/board/agenda/views/pages/backchannel.js.rb | 2 +-
www/board/agenda/views/pages/bootstrap.js.rb | 2 +-
www/board/agenda/views/pages/cache.js.rb | 8 +--
www/board/agenda/views/pages/comments.js.rb | 2 +-
www/board/agenda/views/pages/flagged.js.rb | 2 +-
www/board/agenda/views/pages/fy22.js.rb | 2 +-
www/board/agenda/views/pages/help.js.rb | 2 +-
www/board/agenda/views/pages/index.js.rb | 2 +-
www/board/agenda/views/pages/missing.js.rb | 2 +-
www/board/agenda/views/pages/queue.js.rb | 2 +-
www/board/agenda/views/pages/report.js.rb | 9 +---
www/board/agenda/views/pages/roll-call.js.rb | 4 +-
www/board/agenda/views/pages/search.js.rb | 2 +-
www/board/agenda/views/pages/select-actions.rb | 4 +-
www/board/agenda/views/pages/shepherd.js.rb | 2 +-
49 files changed, 159 insertions(+), 178 deletions(-)
diff --git a/www/board/agenda/Gemfile b/www/board/agenda/Gemfile
index 26031e3..f5a468d 100644
--- a/www/board/agenda/Gemfile
+++ b/www/board/agenda/Gemfile
@@ -13,7 +13,7 @@ end
gem 'rake'
gem 'wunderbar'
-gem 'ruby2js', '>= 2.0.17'
+gem 'ruby2js'
gem 'sinatra', '~> 2.0'
gem 'nokogumbo'
gem 'execjs', ('<2.5.1' if RUBY_VERSION =~ /^1/)
diff --git a/www/board/agenda/README.md b/www/board/agenda/README.md
index 344bbf3..3325165 100644
--- a/www/board/agenda/README.md
+++ b/www/board/agenda/README.md
@@ -118,17 +118,15 @@ At this point, you have something up and running. Let's take a look around.
stylesheet from [bootstrap](http://getbootstrap.com/).
* a `<div>` element with an id of `main` followed by the HTML used
- to present the first page fetched from the server. If you want to
- see a different page, go to that page and hit refresh then view
- source again. This content is nicely indented and other than
- an abundance of `data-reactid` attributes that React uses to keep
- track of things, it is fairly straightforward.
+ to present the first page fetched from the server. If you want to see
+ a different page, go to that page and hit refresh then view source
+ again. This content is nicely indented and is fairly straightforward.
- * a few `<script>` elements that pull in react, jquery, bootstrap, and
+ * a few `<script>` elements that pull in vue, jquery, bootstrap, and
the agenda app itself. I suggest that you leave that for the moment,
we'll come back to it.
- * an inline script that calls `React.render` with a datastructure
+ * an inline script that calls `new Vue` with a datastructure
containing all the data the app needs on the client to do navigation.
Most importantly, this page contains a parsed agenda. Mentally file
that away for later consideration.
@@ -172,23 +170,19 @@ Viewing Source (this time, Actual Code)
* the [views/pages/search.js.rb](views/pages/search.js.rb) file contains the
code for the search page. There are more methods defined here. You will
- find definitions for these methods in the React
- [Lifecycle Methods](http://facebook.github.io/react/docs/component-specs.html#lifecycle-methods).
- You will see logic mixed with presentation. React is deadly serious when
- it adopted the slogan "rethink best practices". What makes this work
- is the component lifecycle that React provides. Components have mutable
+ find definitions for these methods in the Vue
+ [Lifecycle Methods](https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram).
+ You will see logic mixed with presentation. What makes this work
+ is the component lifecycle that Vue provides. Components have mutable
state (which are the variables which are preceded by an `@` sign), and are
passed immutable properties (variables preceded by two `@` signs). Some
methods are prohibited from mutating state (most notably: the `render`
- method). And one method (`componentWillReceiveProps`) even has access
- to the before and after values for properties. Don't get hung up on the
- logic here, but do go to the navigation bar on the top right of the
- browser page, and select `Search` and play with search live.
-
- Two items of special note. `dangerouslySetInnerHTML` is React's
- "don't blame me if things go wrong" way of allowing you to add text
- that you have properly escaped into the content of an element. Also,
- we are directly making use of the browser APIs for updating the
+ method). Don't get hung up on the logic here, but do go to the navigation
+ bar on the top right of the browser page, and select `Search` and play with
+ search live.
+
+ An item of special note: we are directly making use of the browser APIs for
+ updating the
[history](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history)
of the window.
@@ -232,7 +226,7 @@ Viewing Source (this time, Actual Code)
* I mentioned previously that element names that start with a capital
letter are effectively macros. You've seen `Index`, `Search`, and
`AddComment` classes, each of which start with a capital letter. These
- actually are examples of what React calls components that I have described
+ actually are examples of what Vue calls components that I have described
as acting like macros. `views/main.html.rb' contains the 'top'.
[views/app.js.rb](views/app.js.rb) lists all of the files that make up the
client side of the application.
@@ -243,7 +237,7 @@ Viewing Source (this time, Actual Code)
from the js.rb files mentioned above. Undoubtedly you have seen small
amounts of JavaScript before but I suspect that much of this looks foreign.
Nicely indented, commented, vaguely familiar, but still somewhat foreign.
- Many people these days generate JavaScript. Popular with React is something
+ Many people these days generate JavaScript. Popular with Vue is something
called [JSX](http://facebook.github.io/react/docs/jsx-in-depth.html), but
that's both controversial and [doesn't support if
statements](http://facebook.github.io/react/tips/if-else-in-JSX.html).
@@ -298,12 +292,12 @@ Now onto the tests:
(expressed in Ruby, but compiled to JavaScript) can be tested. It does so
by setting up a http server (the code for which is in
[spec/react_server.rb](spec/react_server.rb)) which runs arbitrary scripts
- and returns the results as HTML. This approach excels at testing a React
+ and returns the results as HTML. This approach excels at testing a Vue
component.
* [spec/client_spec.rb](spec/client_spec.rb) takes this a bit further to
do a client side unit test. Instance variables set in tests are passed
- to the React server, and arbitrary JavaScript code can be executed using
+ to the Vue server, and arbitrary JavaScript code can be executed using
this data. Output is in the form of XHTML-style tags which is then
matched against CSS (or xpath) expressions.
@@ -390,7 +384,7 @@ would involve:
[views/layout/header.js.rb](views/layout/header.js.rb)
* Adding the path to the `route` method in
[views/router.js.rb](views/router.js.rb)
- * Adding a React component for the page to `views/pages`
+ * Adding a Vue component for the page to `views/pages`
* Adding any new files to [views/app.js.rb](views/app.js.rb)
* Adding a specification to
[specs/other_views_specs.rb](specs/other_views_specs.rb)
@@ -399,7 +393,7 @@ Adding a new modal dialog would involve:
* Adding a entry to the buttons list in
[views/models/agenda.rb](views/models/agenda.rb)
- * Adding a React component for the form to `views/forms`
+ * Adding a Vue component for the form to `views/forms`
* Adding a server side action to `views/actions`. A number of [actions
from the current agenda
tool](https://svn.apache.org/repos/infra/infrastructure/trunk/projects/whimsy/www/board/agenda/json)
@@ -423,7 +417,7 @@ Nothing is perfect. Here are a few things to watch out for:
[Ruby2JS filters](https://github.com/rubys/ruby2js#filters) reduce this
gap by converting many common Ruby methods calls to JavaScript equivalents
(e.g., `a.include? b` becomes `a.indexOf(b) != -1`). Currently the
- agenda tool makes use of the `react`, `functions` and `require` filters.
+ agenda tool makes use of the `vue`, `functions` and `require` filters.
* In Ruby there isn't a difference between accessing attributes and methods
which have no arguments. In JavaScript there is. To make this work,
@@ -442,7 +436,7 @@ Nothing is perfect. Here are a few things to watch out for:
* In Ruby, `$` is not a legal method name, so this common
alias for `jQuery` isn't directly available. jQuery isn't needed for
- react, but is needed for Bootstrap. As such there will be few places where
+ vue, but is needed for Bootstrap. As such there will be few places where
this will be needed. As previously mentioned, I've considered using
the `~` operator for this.
@@ -455,7 +449,7 @@ Further reading:
framework for developing responsive, mobile first projects on the web
* [capybara](https://github.com/jnicklas/capybara#readme) - helps you test
web applications by simulating how a real user would interact with your app
- * [react](http://facebook.github.io/react/) - a JavaScript library for
+ * [vue](https://vuejs.org/) - a JavaScript library for
building user interfaces
* [ruby2js](https://github.com/rubys/ruby2jw/#readme) - minimal yet
extensible Ruby to JavaScript conversion.
diff --git a/www/board/agenda/main.rb b/www/board/agenda/main.rb
index 3c41022..d294a29 100755
--- a/www/board/agenda/main.rb
+++ b/www/board/agenda/main.rb
@@ -8,7 +8,7 @@ require 'whimsy/asf/agenda'
require 'whimsy/asf/board'
require 'wunderbar/sinatra'
-require 'wunderbar/react'
+require 'wunderbar/vue'
require 'wunderbar/bootstrap/theme'
require 'ruby2js/filter/functions'
require 'ruby2js/filter/require'
diff --git a/www/board/agenda/package.json b/www/board/agenda/package.json
index 9d958e1..6ea8762 100644
--- a/www/board/agenda/package.json
+++ b/www/board/agenda/package.json
@@ -8,7 +8,6 @@
"devDependencies": {
"jsdom": "^11.1.0",
"jquery": "^3.2.1",
- "react": "^15.6.1",
- "react-dom": "^15.6.1"
+ "vue": "^2.4.4"
}
}
diff --git a/www/board/agenda/views/app.js.rb b/www/board/agenda/views/app.js.rb
index 1366739..c7ba655 100644
--- a/www/board/agenda/views/app.js.rb
+++ b/www/board/agenda/views/app.js.rb
@@ -1,3 +1,6 @@
+# config
+require_relative 'vue-config'
+
# common
require_relative 'router'
require_relative 'keyboard'
diff --git a/www/board/agenda/views/buttons/add-comment.js.rb b/www/board/agenda/views/buttons/add-comment.js.rb
index 2445424..5632f01 100644
--- a/www/board/agenda/views/buttons/add-comment.js.rb
+++ b/www/board/agenda/views/buttons/add-comment.js.rb
@@ -8,7 +8,7 @@
# form is dismissed.
#
-class AddComment < React
+class AddComment < Vue
def initialize
@base = @comment = @@item.pending
@disabled = false
diff --git a/www/board/agenda/views/buttons/add-minutes.js.rb b/www/board/agenda/views/buttons/add-minutes.js.rb
index 8f088bd..65ca1a8 100644
--- a/www/board/agenda/views/buttons/add-minutes.js.rb
+++ b/www/board/agenda/views/buttons/add-minutes.js.rb
@@ -1,4 +1,4 @@
-class AddMinutes < React
+class AddMinutes < Vue
def initialize
@disabled = false
end
diff --git a/www/board/agenda/views/buttons/approve.js.rb b/www/board/agenda/views/buttons/approve.js.rb
index fbd1445..d1c1ae6 100644
--- a/www/board/agenda/views/buttons/approve.js.rb
+++ b/www/board/agenda/views/buttons/approve.js.rb
@@ -1,7 +1,7 @@
#
# Approve/Unapprove a report
#
-class Approve < React
+class Approve < Vue
def initialize
@disabled = false
@request = 'approve'
diff --git a/www/board/agenda/views/buttons/attend.js.rb b/www/board/agenda/views/buttons/attend.js.rb
index 40e5621..7d0dd9e 100644
--- a/www/board/agenda/views/buttons/attend.js.rb
+++ b/www/board/agenda/views/buttons/attend.js.rb
@@ -1,7 +1,7 @@
#
# Indicate intention to attend / regrets for meeting
#
-class Attend < React
+class Attend < Vue
def initialize
@disabled = false
end
diff --git a/www/board/agenda/views/buttons/commit.js.rb b/www/board/agenda/views/buttons/commit.js.rb
index fd7264b..eacf2f1 100644
--- a/www/board/agenda/views/buttons/commit.js.rb
+++ b/www/board/agenda/views/buttons/commit.js.rb
@@ -3,7 +3,7 @@
# and allow it to be changed.
#
-class Commit < React
+class Commit < Vue
def initialize
@disabled = false
end
diff --git a/www/board/agenda/views/buttons/draft-minutes.js.rb b/www/board/agenda/views/buttons/draft-minutes.js.rb
index bdf9765..2b506b1 100644
--- a/www/board/agenda/views/buttons/draft-minutes.js.rb
+++ b/www/board/agenda/views/buttons/draft-minutes.js.rb
@@ -1,4 +1,4 @@
-class DraftMinutes < React
+class DraftMinutes < Vue
def initialize
@disabled = true
end
diff --git a/www/board/agenda/views/buttons/email.js.rb b/www/board/agenda/views/buttons/email.js.rb
index 169a068..fa70ffc 100644
--- a/www/board/agenda/views/buttons/email.js.rb
+++ b/www/board/agenda/views/buttons/email.js.rb
@@ -2,7 +2,7 @@
# Send email
#
-class Email < React
+class Email < Vue
def render
_button.btn 'send email', class: self.mailto_class(),
onClick: self.launch_email_client
diff --git a/www/board/agenda/views/buttons/markseen.js.rb b/www/board/agenda/views/buttons/markseen.js.rb
index 4d029cc..96cc182 100644
--- a/www/board/agenda/views/buttons/markseen.js.rb
+++ b/www/board/agenda/views/buttons/markseen.js.rb
@@ -1,7 +1,7 @@
#
# A button that mark all comments as 'seen', with an undo option
#
-class MarkSeen < React
+class MarkSeen < Vue
def initialize
@disabled = false
@label = 'mark seen'
diff --git a/www/board/agenda/views/buttons/message.js.rb b/www/board/agenda/views/buttons/message.js.rb
index f437327..fc0d3bb 100644
--- a/www/board/agenda/views/buttons/message.js.rb
+++ b/www/board/agenda/views/buttons/message.js.rb
@@ -1,7 +1,7 @@
#
# Message area for backchannel
#
-class Message < React
+class Message < Vue
def initialize
@disabled = false
@message = ''
diff --git a/www/board/agenda/views/buttons/post-actions.js.rb b/www/board/agenda/views/buttons/post-actions.js.rb
index f96f3ef..375337f 100644
--- a/www/board/agenda/views/buttons/post-actions.js.rb
+++ b/www/board/agenda/views/buttons/post-actions.js.rb
@@ -1,7 +1,7 @@
#
# Indicate intention to attend / regrets for meeting
#
-class PostActions < React
+class PostActions < Vue
def initialize
@disabled = false
end
diff --git a/www/board/agenda/views/buttons/post.js.rb b/www/board/agenda/views/buttons/post.js.rb
index 757cbd8..22824f4 100644
--- a/www/board/agenda/views/buttons/post.js.rb
+++ b/www/board/agenda/views/buttons/post.js.rb
@@ -4,7 +4,7 @@
# For new resolutions, allow entry of title, but not commit message
# For everything else, allow modification of commit message, but not title
-class Post < React
+class Post < Vue
def initialize
@disabled = false
@alerted = false
@@ -62,13 +62,8 @@ class Post < React
end
end
- # set properties on initial load
- def componentWillMount()
- self.componentWillReceiveProps()
- end
-
# autofocus on report/resolution title/text
- def componentDidMount()
+ def mounted()
jQuery('#post-report-form').on 'shown.bs.modal' do
if @@button.text == 'add resolution'
~'#post-report-title'.focus()
@@ -79,7 +74,7 @@ class Post < React
end
# match form title, input label, and commit message with button text
- def componentWillReceiveProps(newprops)
+ def created(newprops)
case @@button.text
when 'post report'
@header = 'Post Report'
diff --git a/www/board/agenda/views/buttons/publish-minutes.js.rb b/www/board/agenda/views/buttons/publish-minutes.js.rb
index fe80bef..c4f446b 100644
--- a/www/board/agenda/views/buttons/publish-minutes.js.rb
+++ b/www/board/agenda/views/buttons/publish-minutes.js.rb
@@ -1,4 +1,4 @@
-class PublishMinutes < React
+class PublishMinutes < Vue
def initialize
@disabled = false
@previous_title = nil
diff --git a/www/board/agenda/views/buttons/refresh.js.rb b/www/board/agenda/views/buttons/refresh.js.rb
index 9962f5d..5a10062 100644
--- a/www/board/agenda/views/buttons/refresh.js.rb
+++ b/www/board/agenda/views/buttons/refresh.js.rb
@@ -1,7 +1,7 @@
#
# A button that will do a 'svn update' of the agenda on the server
#
-class Refresh < React
+class Refresh < Vue
def initialize
@disabled = false
end
diff --git a/www/board/agenda/views/buttons/reminders.js.rb b/www/board/agenda/views/buttons/reminders.js.rb
index 62e852e..f0506c2 100644
--- a/www/board/agenda/views/buttons/reminders.js.rb
+++ b/www/board/agenda/views/buttons/reminders.js.rb
@@ -3,7 +3,7 @@
# associated button) as well as a second button.
#
-class InitialReminder < React
+class InitialReminder < Vue
def initialize
@disabled = true
@subject = ''
@@ -108,7 +108,7 @@ end
#
# A button for final reminders
#
-class FinalReminder < React
+class FinalReminder < Vue
def render
_button.btn.btn_primary 'send final reminders',
data_toggle: 'modal', data_target: '#reminder-form'
diff --git a/www/board/agenda/views/buttons/showseen.js.rb b/www/board/agenda/views/buttons/showseen.js.rb
index c3c5771..3f31724 100644
--- a/www/board/agenda/views/buttons/showseen.js.rb
+++ b/www/board/agenda/views/buttons/showseen.js.rb
@@ -1,7 +1,7 @@
#
# Show/hide seen items
#
-class ShowSeen < React
+class ShowSeen < Vue
def initialize
@label = 'show seen'
end
diff --git a/www/board/agenda/views/buttons/timestamp.js.rb b/www/board/agenda/views/buttons/timestamp.js.rb
index e6e73db..ca3cb5c 100644
--- a/www/board/agenda/views/buttons/timestamp.js.rb
+++ b/www/board/agenda/views/buttons/timestamp.js.rb
@@ -1,7 +1,7 @@
#
# Timestamp start/stop of meeting
#
-class Timestamp < React
+class Timestamp < Vue
def initialize
@disabled = false
end
diff --git a/www/board/agenda/views/buttons/vote.js.rb b/www/board/agenda/views/buttons/vote.js.rb
index ed34a12..b988e33 100644
--- a/www/board/agenda/views/buttons/vote.js.rb
+++ b/www/board/agenda/views/buttons/vote.js.rb
@@ -1,4 +1,4 @@
-class Vote < React
+class Vote < Vue
def initialize
@disabled = false
end
diff --git a/www/board/agenda/views/elements/additional-info.js.rb b/www/board/agenda/views/elements/additional-info.js.rb
index b6d9774..c7b524f 100644
--- a/www/board/agenda/views/elements/additional-info.js.rb
+++ b/www/board/agenda/views/elements/additional-info.js.rb
@@ -13,7 +13,7 @@
# are unique.
#
-class AdditionalInfo < React
+class AdditionalInfo < Vue
def render
# special notes
_p.notes @@item.notes if @@item.notes
diff --git a/www/board/agenda/views/elements/info.js.rb b/www/board/agenda/views/elements/info.js.rb
index be3ffe7..f2862eb 100644
--- a/www/board/agenda/views/elements/info.js.rb
+++ b/www/board/agenda/views/elements/info.js.rb
@@ -1,4 +1,4 @@
-class Info < React
+class Info < Vue
def render
_dl.dl_horizontal class: @@position do
_dt 'Attach'
diff --git a/www/board/agenda/views/elements/link.js.rb b/www/board/agenda/views/elements/link.js.rb
index 96a8db9..66a3d93 100644
--- a/www/board/agenda/views/elements/link.js.rb
+++ b/www/board/agenda/views/elements/link.js.rb
@@ -3,34 +3,31 @@
# processed locally by calling Main.navigate.
#
-class Link < React
- def initialize
- @attrs = {}
+class Link < Vue
+ def render
+ Vue.createElement(element, options, @@text)
end
- def componentWillMount()
- self.componentWillReceiveProps()
- @attrs.onClick = self.click
+ def element
+ if @@href
+ 'a'
+ else
+ 'span'
+ end
end
- def componentWillReceiveProps(props)
- @text = props.text
+ def options
+ result = {attrs: {}}
- for attr in props
- next unless props[attr]
- @attrs[attr] = props[attr] unless attr == 'text'
+ if @@href
+ result.attrs.href = @@href.gsub(%r{(^|/)\w+/\.\.(/|$)}, '$1')
end
- if props.href
- @element = 'a'
- @attrs.href = props.href.gsub(%r{(^|/)\w+/\.\.(/|$)}, '$1')
- else
- @element = 'span'
- end
- end
+ result.attrs.rel = @@rel if @@rel
- def render
- React.createElement(@element, @attrs, @text)
+ result.on = {click: self.click}
+
+ result
end
def click(event)
diff --git a/www/board/agenda/views/elements/modal-dialog.js.rb b/www/board/agenda/views/elements/modal-dialog.js.rb
index e4970c7..c668eab 100644
--- a/www/board/agenda/views/elements/modal-dialog.js.rb
+++ b/www/board/agenda/views/elements/modal-dialog.js.rb
@@ -5,66 +5,61 @@
# distributed to header, body, and footer sections.
#
-class ModalDialog < React
+class ModalDialog < Vue
def initialize
@header = []
@body = []
@footer = []
end
- def componentWillMount()
- self.componentWillReceiveProps()
- end
-
- def componentWillReceiveProps()
+ def created()
@header.clear()
@body.clear()
@footer.clear()
- @@children.each do |child|
- if child.type == 'h4'
+ $slots.default.each do |slot|
+ if slot.tag == 'h4'
# place h4 elements into the header, adding a modal-title class
- child = self.addClass(child, 'modal-title')
- @header << child
- ModalDialog.h4 = child
+ slot = self.addClass(slot, 'modal-title')
+ @header << slot
- elsif child.type == 'button'
+ elsif slot.tag == 'button'
# place button elements into the footer, adding a btn class
- child = self.addClass(child, 'btn')
- @footer << child
+ slot = self.addClass(slot, 'btn')
+ @footer << slot
- elsif child.type == 'input' or child.type == 'textarea'
+ elsif slot.tag == 'input' or slot.tag == 'textarea'
# wrap input and textarea elements in a form-control,
# add label if present
- child = self.addClass(child, 'form-control')
+ slot = self.addClass(slot, 'form-control')
label = nil
- if child.props.label and child.props.id
- props = {htmlFor: child.props.id}
- if child.props.type == 'checkbox'
- props.className = 'checkbox'
- label = React.createElement('label', props, child,
- child.props.label)
- child.props.delete 'label'
- child = nil
+ if slot.data.attrs.label and slot.data.attrs.id
+ props = {attrs: {for: slot.data.attrs.id}}
+ if slot.data.attrs.type == 'checkbox'
+ props.class = ['checkbox']
+ label = Vue.createElement('label', props, [slot,
+ slot.data.attrs.label])
+ slot.data.attrs.delete 'label'
+ slot = nil
else
- label = React.createElement('label', props, child.props.label)
- child = React.cloneElement(child, label: nil)
+ label = Vue.createElement('label', props, slot.data.attrs.label)
+ slot.data.attrs.delete 'label'
end
end
- @body << React.createElement('div', {className: 'form-group'},
- label, child)
+ @body << Vue.createElement('div', {class: 'form-group'},
+ [label, slot])
else
# place all other elements into the body
- @body << child
+ @body << slot
end
end
end
@@ -92,11 +87,11 @@ class ModalDialog < React
# helper method: add a class to an element, returning new element
def addClass(element, name)
- if not element.props.className
- element = React.cloneElement(element, className: name)
- elsif not element.props.className.split(' ').include? name
- element = React.cloneElement(element,
- className: element.props.className + " #{name}")
+ element.data ||= {}
+ if not element.data.class
+ element.data.class = [name]
+ elsif not element.data.class.include? name
+ element.data.class << name
end
return element
diff --git a/www/board/agenda/views/elements/pns.rb b/www/board/agenda/views/elements/pns.rb
index 8ef23a3..7d910ee 100644
--- a/www/board/agenda/views/elements/pns.rb
+++ b/www/board/agenda/views/elements/pns.rb
@@ -2,7 +2,7 @@
# Determine status of podling name
#
-class PodlingNameSearch < React
+class PodlingNameSearch < Vue
def render
_span.pns title: 'podling name search' do
if Server.podlingnamesearch
diff --git a/www/board/agenda/views/elements/text.js.rb b/www/board/agenda/views/elements/text.js.rb
index 6b6ca02..f034688 100644
--- a/www/board/agenda/views/elements/text.js.rb
+++ b/www/board/agenda/views/elements/text.js.rb
@@ -2,20 +2,18 @@
# Escape text for inclusion in HTML; optionally apply filters
#
-class Text < React
- def componentWillMount()
- self.componentWillReceiveProps()
+class Text < Vue
+ def render
+ _span domPropsInnerHTML: text
end
- def componentWillReceiveProps()
- @text = htmlEscape(@@raw || '')
+ def text
+ result = htmlEscape(@@raw || '')
if @@filters
- @@filters.each { |filter| @text = filter(@text) }
+ @@filters.each { |filter| result = filter(result) }
end
- end
- def render
- _span dangerouslySetInnerHTML: { __html: @text }
+ result
end
end
diff --git a/www/board/agenda/views/keyboard.js.rb b/www/board/agenda/views/keyboard.js.rb
index 4edfc1c..a3ffb80 100644
--- a/www/board/agenda/views/keyboard.js.rb
+++ b/www/board/agenda/views/keyboard.js.rb
@@ -7,19 +7,21 @@ class Keyboard
# keyboard navigation (unless on the search screen)
def (document.body).onkeydown(event)
- return if ~'#search-text'[0] or ~'.modal-open'[0] or ~'.modal.in'[0]
+ return if document.getElementById('search-text') or
+ document.querySelector('modal-open') or
+ document.querySelector('modal-in')
return if not event.altKey and
%w(input textarea).include? document.activeElement.tagName.downcase()
return if event.metaKey or event.ctrlKey
if event.keyCode == 37 # '<-'
- link = ~"a[rel=prev]"[0]
+ link = document.querySelector("a[rel=prev]")
if link
link.click()
return false
end
elsif event.keyCode == 39 # '->'
- link = ~"a[rel=next]"[0]
+ link = document.querySelector("a[rel=next]")
if link
link.click()
return false
diff --git a/www/board/agenda/views/layout/footer.js.rb b/www/board/agenda/views/layout/footer.js.rb
index 3a8d73a..aff616c 100644
--- a/www/board/agenda/views/layout/footer.js.rb
+++ b/www/board/agenda/views/layout/footer.js.rb
@@ -8,7 +8,7 @@
# last flagged <-> first Special order)
#
-class Footer < React
+class Footer < Vue
def render
_footer.navbar.navbar_fixed_bottom class: @@item.color do
@@ -71,9 +71,9 @@ class Footer < React
if @@buttons
@@buttons.each do |button|
if button.text
- React.createElement('button', button.attrs, button.text)
+ Vue.createElement('button', {attrs: button.attrs}, button.text)
elsif button.type
- React.createElement(button.type, button.attrs)
+ Vue.createElement(button.type, {props: button.attrs})
end
end
end
diff --git a/www/board/agenda/views/layout/header.js.rb b/www/board/agenda/views/layout/header.js.rb
index 016906d..7d80926 100644
--- a/www/board/agenda/views/layout/header.js.rb
+++ b/www/board/agenda/views/layout/header.js.rb
@@ -5,7 +5,7 @@
#
# Finally: make info dropdown status 'sticky'
-class Header < React
+class Header < Vue
def initialize
@infodropdown = nil
end
diff --git a/www/board/agenda/views/layout/main.js.rb b/www/board/agenda/views/layout/main.js.rb
index 607895f..a2de545 100644
--- a/www/board/agenda/views/layout/main.js.rb
+++ b/www/board/agenda/views/layout/main.js.rb
@@ -8,7 +8,7 @@
# * Resizing view to leave room for the Header and Footer
#
-class Main < React
+class Main < Vue
# common layout for all pages: header, main, footer, and forms
def render
if not @item
@@ -19,8 +19,8 @@ class Main < React
view = nil
_main do
- React.createElement(@item.view, item: @item,
- ref: proc {|component| Main.view=component})
+ Vue.createElement(@item.view, props: {item: @item,
+ ref: proc {|component| Main.view=component}})
end
_Footer item: @item, buttons: @buttons, options: @options
@@ -29,8 +29,8 @@ class Main < React
if @buttons
@buttons.each do |button|
if button.form
- React.createElement(button.form, item: @item, server: Server,
- button: button)
+ Vue.createElement(button.form, props: {item: @item, server: Server,
+ button: button})
end
end
end
@@ -38,7 +38,7 @@ class Main < React
end
# initial load of the agenda, and route first request
- def componentWillMount()
+ def created()
# copy server info for later use
for prop in @@server
Server[prop] = @@server[prop]
@@ -85,7 +85,7 @@ class Main < React
end
# additional client side initialization
- def componentDidMount()
+ def mounted()
# export navigate and refresh methods
Main.navigate = self.navigate
Main.refresh = self.refresh
@@ -118,7 +118,7 @@ class Main < React
# whenever the window is resized, adjust margins of the main area to
# avoid overlapping the header and footer areas
def window.onresize()
- main = ~'main'
+ main = document.querySelector('main')
if
window.innerHeight <= 400 and
document.body.scrollHeight > window.innerHeight
@@ -130,8 +130,10 @@ class Main < React
else
document.querySelector('footer').style.position = 'fixed'
document.querySelector('header').style.position = 'fixed'
- main.style.marginTop = "#{~'header.navbar'.clientHeight}px"
- main.style.marginBottom = "#{~'footer.navbar'.clientHeight}px"
+ main.style.marginTop =
+ "#{document.querySelector('header.navbar').clientHeight}px"
+ main.style.marginBottom =
+ "#{document.querySelector('footer.navbar').clientHeight}px"
end
if Main.scrollTo == 0 or Main.scrollTo
@@ -160,7 +162,7 @@ class Main < React
end
# after each subsequent re-rendering, resize main window
- def componentDidUpdate()
+ def updated()
window.onresize()
end
end
diff --git a/www/board/agenda/views/pages/action-items.js.rb b/www/board/agenda/views/pages/action-items.js.rb
index e83fb32..c2d033f 100644
--- a/www/board/agenda/views/pages/action-items.js.rb
+++ b/www/board/agenda/views/pages/action-items.js.rb
@@ -3,7 +3,7 @@
# action item status updates.
#
-class ActionItems < React
+class ActionItems < Vue
def initialize
@disabled = false
end
@@ -73,19 +73,20 @@ class ActionItems < React
end
# launch edit dialog when there is a click on the status
- attrs = {onClick: self.updateStatus, className: 'clickable'}
- attrs = {} if Minutes.complete
+ options = {on: {click: self.updateStatus}, class: ['clickable']}
+ options = {} if Minutes.complete
+ options.attrs = {}
# copy action properties to data attributes
for name in action
- attrs["data-#{name}"] = action[name]
+ options.attrs["data-#{name}"] = action[name]
end
# include pending updates
pending = Pending.find_status(action)
attrs['data-status'] = pending.status if pending
- React.createElement('span', attrs) do
+ Vue.createElement('span', options) do
# highlight missing action item status updates
if pending
_span "Status: "
diff --git a/www/board/agenda/views/pages/adjournment.js.rb b/www/board/agenda/views/pages/adjournment.js.rb
index dc41fd3..28556b0 100644
--- a/www/board/agenda/views/pages/adjournment.js.rb
+++ b/www/board/agenda/views/pages/adjournment.js.rb
@@ -2,7 +2,7 @@
# Secretary version of Adjournment section: shows todos
#
-class Adjournment < React
+class Adjournment < Vue
def initialize
Todos.set({
add: [],
@@ -123,7 +123,7 @@ end
# Add, Remove chairs #
########################################################################
-class TodoActions < React
+class TodoActions < Vue
def initialize
@checked = {}
@disabled = true
@@ -219,7 +219,7 @@ end
# Establish actions #
########################################################################
-class EstablishActions < React
+class EstablishActions < Vue
def initialize
@checked = {}
@disabled = true
@@ -308,7 +308,7 @@ end
# Reminder to draft feedback #
########################################################################
-class FeedbackReminder < React
+class FeedbackReminder < Vue
def render
_p 'Draft feedback:'
diff --git a/www/board/agenda/views/pages/backchannel.js.rb b/www/board/agenda/views/pages/backchannel.js.rb
index 47763b1..c45af45 100644
--- a/www/board/agenda/views/pages/backchannel.js.rb
+++ b/www/board/agenda/views/pages/backchannel.js.rb
@@ -2,7 +2,7 @@
# Overall Agenda page: simple table with one row for each item in the index
#
-class Backchannel < React
+class Backchannel < Vue
# place a message input field in the buttons area
def self.buttons()
return [{button: Message}]
diff --git a/www/board/agenda/views/pages/bootstrap.js.rb b/www/board/agenda/views/pages/bootstrap.js.rb
index 202c0e9..7a1a578 100644
--- a/www/board/agenda/views/pages/bootstrap.js.rb
+++ b/www/board/agenda/views/pages/bootstrap.js.rb
@@ -2,7 +2,7 @@
# Blank canvas shown during bootstrapping
#
-class BootStrapPage < React
+class BootStrapPage < Vue
def render
_p ''
end
diff --git a/www/board/agenda/views/pages/cache.js.rb b/www/board/agenda/views/pages/cache.js.rb
index 8f04b7b..d3e6fff 100644
--- a/www/board/agenda/views/pages/cache.js.rb
+++ b/www/board/agenda/views/pages/cache.js.rb
@@ -2,7 +2,7 @@
# A page showing status of caches and service workers
#
-class CacheStatus < React
+class CacheStatus < Vue
def self.buttons()
return [{button: ClearCache}, {button: UnregisterWorker}]
end
@@ -92,7 +92,7 @@ end
#
# A button that clear the cache
#
-class ClearCache < React
+class ClearCache < Vue
def initialize
@disabled = true
end
@@ -131,7 +131,7 @@ end
# A button that removes the service worker. Sadly, it doesn't seem to have
# any affect on the list of registrations that is dynamically returned.
#
-class UnregisterWorker < React
+class UnregisterWorker < Vue
def render
_button.btn.btn_primary 'Unregister ServiceWorker', onClick: self.click
end
@@ -156,7 +156,7 @@ end
# Individual Cache page
#
-class CachePage < React
+class CachePage < Vue
def initialize
@response = {}
@text = ''
diff --git a/www/board/agenda/views/pages/comments.js.rb b/www/board/agenda/views/pages/comments.js.rb
index a7d8b26..a7a2411 100644
--- a/www/board/agenda/views/pages/comments.js.rb
+++ b/www/board/agenda/views/pages/comments.js.rb
@@ -3,7 +3,7 @@
# Conditionally hide comments previously marked as seen.
#
-class Comments < React
+class Comments < Vue
def self.buttons()
buttons = []
diff --git a/www/board/agenda/views/pages/flagged.js.rb b/www/board/agenda/views/pages/flagged.js.rb
index 9afbb99..a5cf73d 100644
--- a/www/board/agenda/views/pages/flagged.js.rb
+++ b/www/board/agenda/views/pages/flagged.js.rb
@@ -2,7 +2,7 @@
# A page showing all flagged reports
#
-class Flagged < React
+class Flagged < Vue
def render
first = true
diff --git a/www/board/agenda/views/pages/fy22.js.rb b/www/board/agenda/views/pages/fy22.js.rb
index b5e7023..1ff5405 100644
--- a/www/board/agenda/views/pages/fy22.js.rb
+++ b/www/board/agenda/views/pages/fy22.js.rb
@@ -1,7 +1,7 @@
#
# FY22 budget worksheet
#
-class FY22 < React
+class FY22 < Vue
def initialize
@budget = (Minutes.started && Minutes.get('budget')) || {
donations: 110,
diff --git a/www/board/agenda/views/pages/help.js.rb b/www/board/agenda/views/pages/help.js.rb
index dddfef9..091dddd 100644
--- a/www/board/agenda/views/pages/help.js.rb
+++ b/www/board/agenda/views/pages/help.js.rb
@@ -1,4 +1,4 @@
-class Help < React
+class Help < Vue
def render
_h3 'Keyboard shortcuts'
_dl.dl_horizontal do
diff --git a/www/board/agenda/views/pages/index.js.rb b/www/board/agenda/views/pages/index.js.rb
index 58424a8..7fbed65 100644
--- a/www/board/agenda/views/pages/index.js.rb
+++ b/www/board/agenda/views/pages/index.js.rb
@@ -2,7 +2,7 @@
# Overall Agenda page: simple table with one row for each item in the index
#
-class Index < React
+class Index < Vue
def render
_header do
_h1 'ASF Board Agenda'
diff --git a/www/board/agenda/views/pages/missing.js.rb b/www/board/agenda/views/pages/missing.js.rb
index db407bb..e48d089 100644
--- a/www/board/agenda/views/pages/missing.js.rb
+++ b/www/board/agenda/views/pages/missing.js.rb
@@ -2,7 +2,7 @@
# A page showing all flagged reports
#
-class Missing < React
+class Missing < Vue
def initialize
@checked = {}
end
diff --git a/www/board/agenda/views/pages/queue.js.rb b/www/board/agenda/views/pages/queue.js.rb
index df10e3f..2c3d43e 100644
--- a/www/board/agenda/views/pages/queue.js.rb
+++ b/www/board/agenda/views/pages/queue.js.rb
@@ -3,7 +3,7 @@
# that are ready for review.
#
-class Queue < React
+class Queue < Vue
def self.buttons()
buttons = [{button: Refresh}]
buttons << {form: Commit} if Pending.count > 0
diff --git a/www/board/agenda/views/pages/report.js.rb b/www/board/agenda/views/pages/report.js.rb
index 89e5d48..4959a93 100644
--- a/www/board/agenda/views/pages/report.js.rb
+++ b/www/board/agenda/views/pages/report.js.rb
@@ -12,7 +12,7 @@
# Filters may be used to highlight or hypertext link portions of the text.
#
-class Report < React
+class Report < Vue
def render
_section.flexbox do
_section do
@@ -56,12 +56,7 @@ class Report < React
end
end
- # check for additional actions on initial render
- def componentWillMount()
- self.componentWillReceiveProps()
- end
-
- def componentWillReceiveProps()
+ def created()
# determine what text filters to run
@filters = [self.linebreak, self.todo, hotlink, self.privates, self.jira]
@filters = [self.localtime, hotlink] if @@item.title == 'Call to order'
diff --git a/www/board/agenda/views/pages/roll-call.js.rb b/www/board/agenda/views/pages/roll-call.js.rb
index 85458b8..08484d9 100644
--- a/www/board/agenda/views/pages/roll-call.js.rb
+++ b/www/board/agenda/views/pages/roll-call.js.rb
@@ -1,7 +1,7 @@
#
# Secretary Roll Call update form
-class RollCall < React
+class RollCall < Vue
def initialize
RollCall.lockFocus = false
@guest = ''
@@ -136,7 +136,7 @@ end
#
# An individual attendee (Director, Executive Officer, or Guest)
#
-class Attendee < React
+class Attendee < Vue
def initialize
# last posted value for notes for this attendee
@base = ''
diff --git a/www/board/agenda/views/pages/search.js.rb b/www/board/agenda/views/pages/search.js.rb
index 2c1a9bf..1ca3543 100644
--- a/www/board/agenda/views/pages/search.js.rb
+++ b/www/board/agenda/views/pages/search.js.rb
@@ -5,7 +5,7 @@
# * keep query string in window location URL in synch
#
-class Search < React
+class Search < Vue
# initialize query text based on data passed to the component
def initialize
@text = @@item.query || ''
diff --git a/www/board/agenda/views/pages/select-actions.rb b/www/board/agenda/views/pages/select-actions.rb
index 85f8223..6a93f4d 100644
--- a/www/board/agenda/views/pages/select-actions.rb
+++ b/www/board/agenda/views/pages/select-actions.rb
@@ -3,7 +3,7 @@
# action item status updates.
#
-class SelectActions < React
+class SelectActions < Vue
def self.buttons()
return [{button: PostActions}]
end
@@ -37,7 +37,7 @@ class SelectActions < React
end
end
-class CandidateAction < React
+class CandidateAction < Vue
def render
_input type: 'checkbox', checked: !@@action.complete,
onChange:-> {@@action.complete = !@@action.complete; self.forceUpdate()}
diff --git a/www/board/agenda/views/pages/shepherd.js.rb b/www/board/agenda/views/pages/shepherd.js.rb
index 54ae353..9e33b76 100644
--- a/www/board/agenda/views/pages/shepherd.js.rb
+++ b/www/board/agenda/views/pages/shepherd.js.rb
@@ -3,7 +3,7 @@
# that are ready for review.
#
-class Shepherd < React
+class Shepherd < Vue
def initialize
@disabled = false
@followup = []
--
To stop receiving notification emails like this one, please contact
['"commits@whimsical.apache.org" <co...@whimsical.apache.org>'].