r3870 - in trunk: . pollen-ui-angular pollen-ui-angular/src pollen-ui-angular/src/main pollen-ui-angular/src/main/resources pollen-ui-angular/src/main/resources/nuiton-js pollen-ui-angular/src/main/webapp pollen-ui-angular/src/main/webapp/css pollen-ui-angular/src/main/webapp/img pollen-ui-angular/src/main/webapp/js pollen-ui-angular/src/main/webapp/js/libs pollen-ui-angular/src/main/webapp/partials pollen-ui-angular/src/test pollen-ui-js pollen-ui-js/src/main/webapp/bundle pollen-ui-js/src
Author: kmorin Date: 2014-03-12 10:46:22 +0100 (Wed, 12 Mar 2014) New Revision: 3870 Url: http://forge.chorem.org/projects/pollen/repository/revisions/3870 Log: add angular ui module Added: trunk/pollen-ui-angular/ trunk/pollen-ui-angular/LICENSE.txt trunk/pollen-ui-angular/README.txt trunk/pollen-ui-angular/changelog.txt trunk/pollen-ui-angular/pollen-ui-angular.iml trunk/pollen-ui-angular/pom.xml trunk/pollen-ui-angular/src/ trunk/pollen-ui-angular/src/main/ trunk/pollen-ui-angular/src/main/java/ trunk/pollen-ui-angular/src/main/resources/ trunk/pollen-ui-angular/src/main/resources/nuiton-js/ trunk/pollen-ui-angular/src/main/resources/nuiton-js/wro.properties trunk/pollen-ui-angular/src/main/resources/nuiton-js/wro.xml trunk/pollen-ui-angular/src/main/webapp/ trunk/pollen-ui-angular/src/main/webapp/css/ trunk/pollen-ui-angular/src/main/webapp/css/bootstrap-datetimepicker.min.css trunk/pollen-ui-angular/src/main/webapp/css/style.css trunk/pollen-ui-angular/src/main/webapp/img/ trunk/pollen-ui-angular/src/main/webapp/img/glyphicons_050_link.png trunk/pollen-ui-angular/src/main/webapp/img/pollen.png trunk/pollen-ui-angular/src/main/webapp/index.html trunk/pollen-ui-angular/src/main/webapp/js/ trunk/pollen-ui-angular/src/main/webapp/js/app.js trunk/pollen-ui-angular/src/main/webapp/js/controllers.js trunk/pollen-ui-angular/src/main/webapp/js/libs/ trunk/pollen-ui-angular/src/main/webapp/js/libs/bootstrap-datetimepicker.min.js trunk/pollen-ui-angular/src/main/webapp/js/libs/jquery.scrollto.js trunk/pollen-ui-angular/src/main/webapp/js/services.js trunk/pollen-ui-angular/src/main/webapp/partials/ trunk/pollen-ui-angular/src/main/webapp/partials/home.html trunk/pollen-ui-angular/src/main/webapp/partials/poll-detail.html trunk/pollen-ui-angular/src/main/webapp/partials/poll-form.html trunk/pollen-ui-angular/src/main/webapp/partials/poll-list.html trunk/pollen-ui-angular/src/test/ trunk/pollen-ui-angular/src/test/java/ trunk/pollen-ui-js/src/main/webapp/img/pollen.png Modified: trunk/pollen-ui-js/pom.xml trunk/pollen-ui-js/src/main/webapp/bundle/Messages.properties trunk/pollen-ui-js/src/main/webapp/css/style.css trunk/pollen-ui-js/src/main/webapp/js/controls/poll_form.js trunk/pollen-ui-js/src/main/webapp/views/poll_form.ejs trunk/pom.xml Copied: trunk/pollen-ui-angular/LICENSE.txt (from rev 3869, trunk/pollen-ui-js/LICENSE.txt) =================================================================== --- trunk/pollen-ui-angular/LICENSE.txt (rev 0) +++ trunk/pollen-ui-angular/LICENSE.txt 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +<http://www.gnu.org/licenses/>. \ No newline at end of file Copied: trunk/pollen-ui-angular/README.txt (from rev 3869, trunk/pollen-ui-js/README.txt) =================================================================== --- trunk/pollen-ui-angular/README.txt (rev 0) +++ trunk/pollen-ui-angular/README.txt 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,58 @@ +POLLEN +------ + +Pollen est une application Web de sondages en ligne qui permet de créer et de +gérer des sondages avec différents types de choix (texte, date, image). +Les votants peuvent participer au sondage en suivant un lien qui identifie le +sondage. + + +INSTALLATION +------------ + +Pour installer l'application il suffit de déployer l'archive war dans un +conteneur Web comme Tomcat. + +Par défaut une base de données H2 est créée dans le répertoire /tmp. +Pour modifier ce comportement par défaut il suffit de créer le fichier +/etc/pollen.properties et de le remplir avec les propriétés suivantes : + + # Configuration de la base de données + hibernate.show_sql=false + hibernate.dialect=org.hibernate.dialect.H2Dialect + hibernate.connection.username=username + hibernate.connection.password=password + hibernate.connection.driver_class=org.h2.Driver + hibernate.connection.url=jdbc:h2:file://tmp/pollen/pollen + + # Répertoire des images transférées + upImgDir=/tmp/pollen/uploadedImages + + # Taille maximal des images transférées (en octets) + upload.filesize-max=1048576 + upload.requestsize-max=10485760 + + # Configuration de l'envoi d'emails automatiques + email_host=smtp.free.fr + email_port=25 + email_from=bot@pollen.org + + # Répertoire des flux de syndication (Atom) + feedDir=/tmp/pollen/feeds + + # Adresse du site (utilisée pour les emails de rappel) + siteUrl=http://www.site.org/pollen/ + +Pour une base PostgreSQL on aura : + + hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect + hibernate.connection.driver_class=org.postgresql.Driver + hibernate.default_schema=public + +Il peut-être nécessaire de redéployer l'application après avoir modifié ce +fichier. + +Un utilisateur avec les droits d'administration est créé automatiquement +(identifiant "admin", mot de passe "pollen"). Par mesure de sécurité il est +important de supprimer cet utilisateur après avoir créer un autre compte +administrateur. Copied: trunk/pollen-ui-angular/changelog.txt (from rev 3869, trunk/pollen-ui-js/changelog.txt) =================================================================== --- trunk/pollen-ui-angular/changelog.txt (rev 0) +++ trunk/pollen-ui-angular/changelog.txt 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,40 @@ +ChangeLog +========= +1.2.3 +- Anomalie #101: Sondage à type de dépouillement: Number + +1.2.2 +- Rename favicon to favicon.png +- Use war launcher from nuiton-utils project +- Evolution #96: Nouveau type de consultation: un nombre + +1.2.1 +- Erreur lors de la modification de son vote Issue: 87 + +1.2.0 +- Fixed a performance problem in the file upload with Winstone. +- Global dependencies update +- Use hudson version of winstone web server (original seam unmaintained) +- Fix slf4j dependency bug between api & impl +- Evol #54 +- Ano #49 + +1.1.0 +- liste de votants à partir d'un serveur ldap +- export de sondage +- flux de syndication atom +- création d'un sondage par copie d'un ancien +- sondages par groupes +- administration des sondages et des utilisateurs +- suppression de choix, de votes et de commentaires +- liste des sondages auxquels l'utilisateur a participé +- URL forgée pour les votes restreints + +1.0.1 +- refonte de la création de sondage +- sondages restreints +- listes de votants +- service de migration + +1.0.0 +- initiale release Added: trunk/pollen-ui-angular/pollen-ui-angular.iml =================================================================== --- trunk/pollen-ui-angular/pollen-ui-angular.iml (rev 0) +++ trunk/pollen-ui-angular/pollen-ui-angular.iml 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false"> + <output url="file://$MODULE_DIR$/target/classes" /> + <output-test url="file://$MODULE_DIR$/target/test-classes" /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> + <excludeFolder url="file://$MODULE_DIR$/target" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> + Added: trunk/pollen-ui-angular/pom.xml =================================================================== --- trunk/pollen-ui-angular/pom.xml (rev 0) +++ trunk/pollen-ui-angular/pom.xml 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.chorem</groupId> + <artifactId>pollen</artifactId> + <version>2.0-SNAPSHOT</version> + </parent> + + <name>Pollen :: UI (Angular) </name> + <description>Pollen UI</description> + + <groupId>org.chorem.pollen</groupId> + <artifactId>pollen-ui-angular</artifactId> + <packaging>pom</packaging> + + <properties> + + <!-- Post Release configuration --> + <skipPostRelease>false</skipPostRelease> + </properties> + + <build> + + <plugins> + + <plugin> + <groupId>ro.isdc.wro4j</groupId> + <artifactId>wro4j-maven-plugin</artifactId> + <version>1.7.0</version> + <dependencies> + <dependency> + <groupId>org.nuiton.js</groupId> + <artifactId>nuiton-js-wro</artifactId> + <version>1.0</version> + </dependency> + + <dependency> + <groupId>org.nuiton.js</groupId> + <artifactId>nuiton-js-jquery</artifactId> + <version>1.9.1-2</version> + </dependency> + + <dependency> + <groupId>org.nuiton.js</groupId> + <artifactId>nuiton-js-bootstrap</artifactId> + <version>2.3.2-1</version> + </dependency> + + <dependency> + <groupId>org.nuiton.js</groupId> + <artifactId>nuiton-js-jquery-i18n-properties</artifactId> + <version>1.0.9-1</version> + </dependency> + + <dependency> + <groupId>org.nuiton.js</groupId> + <artifactId>nuiton-js-moment</artifactId> + <version>2.0.0-1</version> + </dependency> + + </dependencies> + + <executions> + <execution> + <phase>compile</phase> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + + <configuration> + <targetGroups>pollen-ui-angular</targetGroups> + <minimize>true</minimize> + <wroFile>${basedir}/src/main/resources/nuiton-js/wro.xml</wroFile> + <extraConfigFile>${basedir}/src/main/resources/nuiton-js/wro.properties</extraConfigFile> + <contextFolder>${basedir}/src/main/webapp/</contextFolder> + <destinationFolder>${basedir}/src/main/webapp/</destinationFolder> + <wroManagerFactory>org.nuiton.js.wro.NuitonJsMavenWroManagerFactory</wroManagerFactory> + </configuration> + </plugin> + + </plugins> + </build> + +</project> Copied: trunk/pollen-ui-angular/src/main/resources/nuiton-js/wro.properties (from rev 3869, trunk/pollen-ui-js/src/main/resources/nuiton-js/wro.properties) =================================================================== --- trunk/pollen-ui-angular/src/main/resources/nuiton-js/wro.properties (rev 0) +++ trunk/pollen-ui-angular/src/main/resources/nuiton-js/wro.properties 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,26 @@ +### +# #%L +# Pollen :: UI (JS) +# $Id$ +# $HeadURL$ +# %% +# Copyright (C) 2009 - 2013 CodeLutin +# %% +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# #L% +### +debug=false +preProcessors=forceCssDataUri,cssUrlRewriting,cssImport,semicolonAppender,cssMinJawr +postProcessors=cssVariables,jsMin +uriLocators=uri,classpath \ No newline at end of file Copied: trunk/pollen-ui-angular/src/main/resources/nuiton-js/wro.xml (from rev 3869, trunk/pollen-ui-js/src/main/resources/nuiton-js/wro.xml) =================================================================== --- trunk/pollen-ui-angular/src/main/resources/nuiton-js/wro.xml (rev 0) +++ trunk/pollen-ui-angular/src/main/resources/nuiton-js/wro.xml 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,36 @@ +<!-- + #%L + Pollen :: UI (JS) + $Id$ + $HeadURL$ + %% + Copyright (C) 2009 - 2013 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> +<groups xmlns="http://www.isdc.ro/wro"> + + <group name='pollen-ui-angular'> + <group-ref>jquery</group-ref> + <group-ref>bootstrap-responsive</group-ref> + <group-ref>jquery.i18n.properties</group-ref> + <group-ref>moment</group-ref> + + <!-- scpecifique nuiton profiling --> + <!--<css>/nuiton-profiling.css</css>--> + <!--<js>/nuiton-profiling.js</js>--> + </group> + +</groups> Property changes on: trunk/pollen-ui-angular/src/main/webapp ___________________________________________________________________ Added: svn:ignore + pollen-ui-angular.css pollen-ui-angular.js Copied: trunk/pollen-ui-angular/src/main/webapp/css/bootstrap-datetimepicker.min.css (from rev 3869, trunk/pollen-ui-js/src/main/webapp/css/bootstrap-datetimepicker.min.css) =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/css/bootstrap-datetimepicker.min.css (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/css/bootstrap-datetimepicker.min.css 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,8 @@ +/*! + * Datepicker for Bootstrap + * + * Copyright 2012 Stefan Petre + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-datetimepicker-widget{top:0;left:0;width:250px;padding:4px;margin-top:1px;z-index:3000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.bootstrap-datetimepicker-widget:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,0.2);position:absolute;top:-7px;left:6px}.bootstrap-datetimepicker-widget:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:7px}.bootstrap-datetimepicker-widget.pull-right:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.pull-right:after{left:auto;right:7px}.bootstrap-datetimepicker-widget>ul{list-style-type:none;margin:0}.bootstrap-datetimepicker-widget .timepicker-hour,.bootstrap-datetimepicker-widget .timepicker-minute,.bootstrap-datetimepicker-widget .timepicker-second{width:100%;font-weight:bold;font-size:1.2em}.bootstrap-datetimepicker-widget table[data-hour-format="12"] .separator{width:4px;padding:0;margin:0}.bootstrap-datetimepicker-widget .datepicker>div{display:none}.bootstrap-datetimepicker-widget .picker-switch{text-align:center}.bootstrap-datetimepicker-widget table{width:100%;margin:0}.bootstrap-datetimepicker-widget td,.bootstrap-datetimepicker-widget th{text-align:center;width:20px;height:20px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.bootstrap-datetimepicker-widget td.day:hover,.bootstrap-datetimepicker-widget td.hour:hover,.bootstrap-datetimepicker-widget td.minute:hover,.bootstrap-datetimepicker-widget td.second:hover{background:#eee;cursor:pointer}.bootstrap-datetimepicker-widget td.old,.bootstrap-datetimepicker-widget td.new{color:#999}.bootstrap-datetimepicker-widget td.active,.bootstrap-datetimepicker-widget td.active:hover{color:#fff;background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.bootstrap-datetimepicker-widget td.active:hover,.bootstrap-datetimepicker-widget td.active:hover:hover,.bootstrap-datetimepicker-widget td.active:active,.bootstrap-datetimepicker-widget td.active:hover:active,.bootstrap-datetimepicker-widget td.active.active,.bootstrap-datetimepicker-widget td.active:hover.active,.bootstrap-datetimepicker-widget td.active.disabled,.bootstrap-datetimepicker-widget td.active:hover.disabled,.bootstrap-datetimepicker-widget td.active[disabled],.bootstrap-datetimepicker-widget td.active:hover[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.bootstrap-datetimepicker-widget td.active:active,.bootstrap-datetimepicker-widget td.active:hover:active,.bootstrap-datetimepicker-widget td.active.active,.bootstrap-datetimepicker-widget td.active:hover.active{background-color:#039 \9}.bootstrap-datetimepicker-widget td.disabled,.bootstrap-datetimepicker-widget td.disabled:hover{background:0;color:#999;cursor:not-allowed}.bootstrap-datetimepicker-widget td span{display:block;width:47px;height:54px;line-height:54px;float:left;margin:2px;cursor:pointer;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.bootstrap-datetimepicker-widget td span:hover{background:#eee}.bootstrap-datetimepicker-widget td span.active{color:#fff;background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.bootstrap-datetimepicker-widget td span.active:hover,.bootstrap-datetimepicker-widget td span.active:active,.bootstrap-datetimepicker-widget td span.active.active,.bootstrap-datetimepicker-widget td span.active.disabled,.bootstrap-datetimepicker-widget td span.active[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.bootstrap-datetimepicker-widget td span.active:active,.bootstrap-datetimepicker-widget td span.active.active{background-color:#039 \9}.bootstrap-datetimepicker-widget td span.old{color:#999}.bootstrap-datetimepicker-widget td span.disabled,.bootstrap-datetimepicker-widget td span.disabled:hover{background:0;color:#999;cursor:not-allowed}.bootstrap-datetimepicker-widget th.switch{width:145px}.bootstrap-datetimepicker-widget th.next,.bootstrap-datetimepicker-widget th.prev{font-size:21px}.bootstrap-datetimepicker-widget th.disabled,.bootstrap-datetimepicker-widget th.disabled:hover{background:0;color:#999;cursor:not-allowed}.bootstrap-datetimepicker-widget thead tr:first-child th{cursor:pointer}.bootstrap-datetimepicker-widget thead tr:first-child th:hover{background:#eee}.input-append.date .add-on i,.input-prepend.date .add-on i{display:block;cursor:pointer;width:16px;height:16px}.bootstrap-datetimepicker-widget.left-oriented:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.left-oriented:after{left:auto;right:7px} \ No newline at end of file Copied: trunk/pollen-ui-angular/src/main/webapp/css/style.css (from rev 3869, trunk/pollen-ui-js/src/main/webapp/css/style.css) =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/css/style.css (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/css/style.css 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,104 @@ +/* + * #%L + * Pollen :: UI (JS) + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2013 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +.dropdown-menu.form { + padding: 0; + padding-top: 15px; +} + +.dropdown-menu.form > form { + margin: 0; +} + +.dropdown-menu.form .form-actions { + padding: 15px 20px 20px; + margin-bottom: 0; + border-radius: 0 0 6px 6px; +} + +.dropdown-menu.form .control-group { + padding: 0 15px; + margin-bottom: 5px; +} + +.noListStyle { + list-style-type: none; +} + +.noListStyle i { + margin-right: 5px; +} + +.link { + cursor: pointer; +} + +.icon-link { + background-image: url(../img/glyphicons_050_link.png); + background-position: center; + background-repeat: no-repeat; + background-size: 12px 14px; +} + +i.bigger { + width: 24px; + height: 24px; + background-size: 21px 23px; +} + +i.icon-collapse { + background-position: -288px -120px; +} + +.collapsed i.icon-collapse { + background-position: -313px -119px; +} + +.list.alternate-colors > div { + padding: 10px 20px; +} + +.list.alternate-colors > .even { + background-color: rgb(245, 245, 245); +} + +.list.alternate-colors .footer { + color: rgb(150, 150, 150); +} + +#voteForm .choice { + background-position: center; + background-repeat: no-repeat; + text-align: center; +} + +#voteForm .selected { + background-color: #6f6; +} + +#voteForm .notSelected { + background-color: #f66; +} + +#voteForm .voteBeforeChoice { + background-color: #ff6; +} \ No newline at end of file Copied: trunk/pollen-ui-angular/src/main/webapp/img/glyphicons_050_link.png (from rev 3869, trunk/pollen-ui-js/src/main/webapp/img/glyphicons_050_link.png) =================================================================== (Binary files differ) Added: trunk/pollen-ui-angular/src/main/webapp/img/pollen.png =================================================================== (Binary files differ) Property changes on: trunk/pollen-ui-angular/src/main/webapp/img/pollen.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/pollen-ui-angular/src/main/webapp/index.html =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/index.html (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/index.html 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,113 @@ +<html lang="en" ng-app="pollen"> +<head> + <title>Pollen</title> + <link rel="stylesheet" href="pollen-ui-angular.css"></link> + <link rel="stylesheet" href="css/bootstrap-datetimepicker.min.css"></link> + <link rel="stylesheet" href="css/style.css"></link> + + <script src="pollen-ui-angular.js"></script> + <script src="js/libs/jquery.scrollto.js"></script> + <script src="js/libs/bootstrap-datetimepicker.min.js"></script> + + <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script> + <script src="js/app.js"></script> + <script src="js/controllers.js"></script> + <script src="js/services.js"></script> + <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular-resource.js"></script> +</head> +<body> + + <div class="navbar navbar-inverse navbar-static-top"> + + <div class="navbar-inner"> + <a class="brand" href="#">pollen.app.title</a> + + <ul class="nav"> + <li><a href="#">pollen.menu.home</a></li> + + <li class="dropdown"> + <a href="#" role="button" class="dropdown-toggle" data-toggle="dropdown"> + pollen.menu.polls.label <strong class="caret"></strong> + </a> + + <ul class="dropdown-menu" role="menu"> + <li role="presentation"> + <a href="#/polls/create" role="menuitem" tabIndex="-1">pollen.menu.polls.create</a> + </li> + + <li class="divider" role="presentation" ng-show="currentUser.login"></li> + + <li role="presentation" ng-show="currentUser.login"> + <a href="#/polls/" role="menuitem" tabIndex="-1">pollen.menu.polls.list</a> + </li> + + </ul> + </li> + </ul> + + <ul class="nav pull-right"> + <li ng-show="!currentUser.login"> + <a href="#/user/register/">pollen.menu.register</a> + </li> + + <li class="divider-vertical" ng-show="!currentUser.login"></li> + + <li class="dropdown" ng-show="!currentUser.login"> + <a href="#" role="button" class="dropdown-toggle" data-toggle="dropdown"> + pollen.menu.login.label <strong class="caret"></strong> + </a> + + <div class="dropdown-menu form" role="menu"> + <form id='loginForm'> + + <div class="control-group"> + <label class="control-label">pollen.menu.login.form.login.label</label> + <input type="text" name='login' placeholder="pollen.menu.login.form.login.placeholder"/> + <span class="help-block hide"></span> + </div> + + <div class="control-group"> + <label class="control-label" >pollen.menu.login.form.password.label</label> + <input type="password" name='password' placeholder="pollen.menu.login.form.password.placeholder"/> + <span class="help-block hide"></span> + </div> + + <div class="control-group"> + <label class="control-label checkbox" > + <input type="checkbox" name='rememberMe'> pollen.menu.login.form.rememberMe.label + </label> + </div> + + <div class="form-actions"> + <button type="submit" class="btn btn-primary">pollen.menu.login.form.button</button> + </div> + + </form> + </div> + </li> + + <li class="dropdown" ng-show="currentUser.login"> + <a href="#" role="button" class="dropdown-toggle" data-toggle="dropdown"> + {{ currentUser.name }} <strong class="caret"></strong> + </a> + + <ul class="dropdown-menu" role="menu"> + <li role="presentation"> + <a href="#/user/edit/{{currentUser.id}}">pollen.menu.user.profile</a> + </li> + + <li class="divider" role="presentation"></li> + <li role="presentation"> + <a id='menuItemLogout'>pollen.menu.logout</a> + </li> + + </ul> + </li> + </ul> + </div> + </div> + + <div ng-view class='container' id="content"></div> + +</body> +</html> \ No newline at end of file Added: trunk/pollen-ui-angular/src/main/webapp/js/app.js =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/js/app.js (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/js/app.js 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,13 @@ +angular.module('pollen', ["pollenServices"]).config(['$routeProvider', function($routeProvider) { + + $routeProvider.when('/', {templateUrl: 'partials/home.html', controller: HomeCtrl}) + .when('/polls', {templateUrl: 'partials/poll-list.html', controller: PollListCtrl}) + .when('/polls/create', {templateUrl: 'partials/poll-form.html', controller: PollCreationCtrl}) + .when('/polls/:pollId', {templateUrl: 'partials/poll-detail.html', controller: PollDetailCtrl}) + .otherwise({redirectTo: '/'}); + +}]).config(['$httpProvider', function($httpProvider) { + + $httpProvider.defaults.useXDomain = true; + delete $httpProvider.defaults.headers.common['X-Requested-With']; +}]);; \ No newline at end of file Added: trunk/pollen-ui-angular/src/main/webapp/js/controllers.js =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/js/controllers.js (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/js/controllers.js 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,66 @@ +function HomeCtrl($scope, $http) { + +} + +function PollCreationCtrl($scope, $http) { + $http.get('http://localhost:8080/pollen/v1/polls/new?choiceType=TEXT').success(function(data) { + data.choices = [{}, {}]; + $scope.poll = data; + $scope.step = 1; + }); + + $scope.prev = function() { + $scope.step--; + } + + $scope.next = function() { + $scope.step++; + } + + $scope.addChoice = function() { + $scope.poll.choices.push({}); + } +} + +function PollListCtrl($scope, $http) { + $http.get('http://localhost:8080/pollen/v1/polls').success(function(data) { + $scope.polls = data; + }); +} + +function PollDetailCtrl($scope, $http, $routeParams) { + $http({url: "http://localhost:8080/pollen/v1/polls/" + $routeParams.pollId, method: "GET"}).success(function(data) { + $scope.poll = data; + }); + + $http({url: "http://localhost:8080/pollen/v1/polls/" + $routeParams.pollId + "/choices", method: "GET"}).success(function(data) { + $scope.choices = data; + }); + + $http({url: "http://localhost:8080/pollen/v1/polls/" + $routeParams.pollId + "/comments", method: "GET"}).success(function(data) { + $scope.comments = data; + }).error(function() { + $scope.comments = []; + }); + + $http({url: "http://localhost:8080/pollen/v1/polls/" + $routeParams.pollId + "/votes", method: "GET"}).success(function(data) { + $scope.votes = data; + }).error(function() { + $scope.votes = []; + }); + + $scope.author = ""; + $scope.text = ""; + + $scope.addComment = function() { + var comment = { + author: this.author, + text: this.text, + postDate: new Date().getTime() + }; + this.comments.push(comment); + this.author = ""; + this.text = ""; + } + +} \ No newline at end of file Copied: trunk/pollen-ui-angular/src/main/webapp/js/libs/bootstrap-datetimepicker.min.js (from rev 3869, trunk/pollen-ui-js/src/main/webapp/js/libs/bootstrap-datetimepicker.min.js) =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/js/libs/bootstrap-datetimepicker.min.js (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/js/libs/bootstrap-datetimepicker.min.js 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,26 @@ +/** + * @license + * ========================================================= + * bootstrap-datetimepicker.js + * http://www.eyecon.ro/bootstrap-datepicker + * ========================================================= + * Copyright 2012 Stefan Petre + * + * Contributions: + * - Andrew Rowls + * - Thiago de Arruda + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= + */ +(function($){var smartPhone=window.orientation!=undefined;var DateTimePicker=function(element,options){this.id=dpgId++;this.init(element,options)};var dateToDate=function(dt){if(typeof dt==="string"){return new Date(dt)}return dt};DateTimePicker.prototype={constructor:DateTimePicker,init:function(element,options){var icon;if(!(options.pickTime||options.pickDate))throw new Error("Must choose at least one picker");this.options=options;this.$element=$(element);this.language=options.language in dates?options.language:"en";this.pickDate=options.pickDate;this.pickTime=options.pickTime;this.isInput=this.$element.is("input");this.component=false;if(this.$element.find(".input-append")||this.$element.find(".input-prepend"))this.component=this.$element.find(".add-on");this.format=options.format;if(!this.format){if(this.isInput)this.format=this.$element.data("format");else this.format=this.$element.find("input").data("format");if(!this.format)this.format="MM/dd/yyyy"}this._compileFormat();if(this.component){icon=this.component.find("i")}if(this.pickTime){if(icon&&icon.length)this.timeIcon=icon.data("time-icon");if(!this.timeIcon)this.timeIcon="icon-time";icon.addClass(this.timeIcon)}if(this.pickDate){if(icon&&icon.length)this.dateIcon=icon.data("date-icon");if(!this.dateIcon)this.dateIcon="icon-calendar";icon.removeClass(this.timeIcon);icon.addClass(this.dateIcon)}this.widget=$(getTemplate(this.timeIcon,options.pickDate,options.pickTime,options.pick12HourFormat,options.pickSeconds,options.collapse)).appendTo("body");this.minViewMode=options.minViewMode||this.$element.data("date-minviewmode")||0;if(typeof this.minViewMode==="string"){switch(this.minViewMode){case"months":this.minViewMode=1;break;case"years":this.minViewMode=2;break;default:this.minViewMode=0;break}}this.viewMode=options.viewMode||this.$element.data("date-viewmode")||0;if(typeof this.viewMode==="string"){switch(this.viewMode){case"months":this.viewMode=1;break;case"years":this.viewMode=2;break;default:this.viewMode=0;break}}this.startViewMode=this.viewMode;this.weekStart=options.weekStart||this.$element.data("date-weekstart")||0;this.weekEnd=this.weekStart===0?6:this.weekStart-1;this.setStartDate(options.startDate||this.$element.data("date-startdate"));this.setEndDate(options.endDate||this.$element.data("date-enddate"));this.fillDow();this.fillMonths();this.fillHours();this.fillMinutes();this.fillSeconds();this.update();this.showMode();this._attachDatePickerEvents()},show:function(e){this.widget.show();this.height=this.component?this.component.outerHeight():this.$element.outerHeight();this.place();this.$element.trigger({type:"show",date:this._date});this._attachDatePickerGlobalEvents();if(e){e.stopPropagation();e.preventDefault()}},disable:function(){this.$element.find("input").prop("disabled",true);this._detachDatePickerEvents()},enable:function(){this.$element.find("input").prop("disabled",false);this._attachDatePickerEvents()},hide:function(){var collapse=this.widget.find(".collapse");for(var i=0;i<collapse.length;i++){var collapseData=collapse.eq(i).data("collapse");if(collapseData&&collapseData.transitioning)return}this.widget.hide();this.viewMode=this.startViewMode;this.showMode();this.set();this.$element.trigger({type:"hide",date:this._date});this._detachDatePickerGlobalEvents()},set:function(){var formatted="";if(!this._unset)formatted=this.formatDate(this._date);if(!this.isInput){if(this.component){var input=this.$element.find("input");input.val(formatted);this._resetMaskPos(input)}this.$element.data("date",formatted)}else{this.$element.val(formatted);this._resetMaskPos(this.$element)}},setValue:function(newDate){if(!newDate){this._unset=true}else{this._unset=false}if(typeof newDate==="string"){this._date=this.parseDate(newDate)}else if(newDate){this._date=new Date(newDate)}this.set();this.viewDate=UTCDate(this._date.getUTCFullYear(),this._date.getUTCMonth(),1,0,0,0,0);this.fillDate();this.fillTime()},getDate:function(){if(this._unset)return null;return new Date(this._date.valueOf())},setDate:function(date){if(!date)this.setValue(null);else this.setValue(date.valueOf())},setStartDate:function(date){if(date instanceof Date){this.startDate=date}else if(typeof date==="string"){this.startDate=new UTCDate(date);if(!this.startDate.getUTCFullYear()){this.startDate=-Infinity}}else{this.startDate=-Infinity}if(this.viewDate){this.update()}},setEndDate:function(date){if(date instanceof Date){this.endDate=date}else if(typeof date==="string"){this.endDate=new UTCDate(date);if(!this.endDate.getUTCFullYear()){this.endDate=Infinity}}else{this.endDate=Infinity}if(this.viewDate){this.update()}},getLocalDate:function(){if(this._unset)return null;var d=this._date;return new Date(d.getUTCFullYear(),d.getUTCMonth(),d.getUTCDate(),d.getUTCHours(),d.getUTCMinutes(),d.getUTCSeconds(),d.getUTCMilliseconds())},setLocalDate:function(localDate){if(!localDate)this.setValue(null);else this.setValue(Date.UTC(localDate.getFullYear(),localDate.getMonth(),localDate.getDate(),localDate.getHours(),localDate.getMinutes(),localDate.getSeconds(),localDate.getMilliseconds()))},place:function(){var position="absolute";var offset=this.component?this.component.offset():this.$element.offset();this.width=this.component?this.component.outerWidth():this.$element.outerWidth();offset.top=offset.top+this.height;var $window=$(window);if(this.options.width!=undefined){this.widget.width(this.options.width)}if(this.options.orientation=="left"){this.widget.addClass("left-oriented");offset.left=offset.left-this.widget.width()+20}if(this._isInFixed()){position="fixed";offset.top-=$window.scrollTop();offset.left-=$window.scrollLeft()}if($window.width()<offset.left+this.widget.outerWidth()){offset.right=$window.width()-offset.left-this.width;offset.left="auto";this.widget.addClass("pull-right")}else{offset.right="auto";this.widget.removeClass("pull-right")}this.widget.css({position:position,top:offset.top,left:offset.left,right:offset.right})},notifyChange:function(){this.$element.trigger({type:"changeDate",date:this.getDate(),localDate:this.getLocalDate()})},update:function(newDate){var dateStr=newDate;if(!dateStr){if(this.isInput){dateStr=this.$element.val()}else{dateStr=this.$element.find("input").val()}if(dateStr){this._date=this.parseDate(dateStr)}if(!this._date){var tmp=new Date;this._date=UTCDate(tmp.getFullYear(),tmp.getMonth(),tmp.getDate(),tmp.getHours(),tmp.getMinutes(),tmp.getSeconds(),tmp.getMilliseconds())}}this.viewDate=UTCDate(this._date.getUTCFullYear(),this._date.getUTCMonth(),1,0,0,0,0);this.fillDate();this.fillTime()},fillDow:function(){var dowCnt=this.weekStart;var html=$("<tr>");while(dowCnt<this.weekStart+7){html.append('<th class="dow">'+dates[this.language].daysMin[dowCnt++%7]+"</th>")}this.widget.find(".datepicker-days thead").append(html)},fillMonths:function(){var html="";var i=0;while(i<12){html+='<span class="month">'+dates[this.language].monthsShort[i++]+"</span>"}this.widget.find(".datepicker-months td").append(html)},fillDate:function(){var year=this.viewDate.getUTCFullYear();var month=this.viewDate.getUTCMonth();var currentDate=UTCDate(this._date.getUTCFullYear(),this._date.getUTCMonth(),this._date.getUTCDate(),0,0,0,0);var startYear=typeof this.startDate==="object"?this.startDate.getUTCFullYear():-Infinity;var startMonth=typeof this.startDate==="object"?this.startDate.getUTCMonth():-1;var endYear=typeof this.endDate==="object"?this.endDate.getUTCFullYear():Infinity;var endMonth=typeof this.endDate==="object"?this.endDate.getUTCMonth():12;this.widget.find(".datepicker-days").find(".disabled").removeClass("disabled");this.widget.find(".datepicker-months").find(".disabled").removeClass("disabled");this.widget.find(".datepicker-years").find(".disabled").removeClass("disabled");this.widget.find(".datepicker-days th:eq(1)").text(dates[this.language].months[month]+" "+year);var prevMonth=UTCDate(year,month-1,28,0,0,0,0);var day=DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(),prevMonth.getUTCMonth());prevMonth.setUTCDate(day);prevMonth.setUTCDate(day-(prevMonth.getUTCDay()-this.weekStart+7)%7);if(year==startYear&&month<=startMonth||year<startYear){this.widget.find(".datepicker-days th:eq(0)").addClass("disabled")}if(year==endYear&&month>=endMonth||year>endYear){this.widget.find(".datepicker-days th:eq(2)").addClass("disabled")}var nextMonth=new Date(prevMonth.valueOf());nextMonth.setUTCDate(nextMonth.getUTCDate()+42);nextMonth=nextMonth.valueOf();var html=[];var row;var clsName;while(prevMonth.valueOf()<nextMonth){if(prevMonth.getUTCDay()===this.weekStart){row=$("<tr>");html.push(row)}clsName="";if(prevMonth.getUTCFullYear()<year||prevMonth.getUTCFullYear()==year&&prevMonth.getUTCMonth()<month){clsName+=" old"}else if(prevMonth.getUTCFullYear()>year||prevMonth.getUTCFullYear()==year&&prevMonth.getUTCMonth()>month){clsName+=" new"}if(prevMonth.valueOf()===currentDate.valueOf()){clsName+=" active"}if(prevMonth.valueOf()+864e5<=this.startDate){clsName+=" disabled"}if(prevMonth.valueOf()>this.endDate){clsName+=" disabled"}row.append('<td class="day'+clsName+'">'+prevMonth.getUTCDate()+"</td>");prevMonth.setUTCDate(prevMonth.getUTCDate()+1)}this.widget.find(".datepicker-days tbody").empty().append(html);var currentYear=this._date.getUTCFullYear();var months=this.widget.find(".datepicker-months").find("th:eq(1)").text(year).end().find("span").removeClass("active");if(currentYear===year){months.eq(this._date.getUTCMonth()).addClass("active")}if(currentYear-1<startYear){this.widget.find(".datepicker-months th:eq(0)").addClass("disabled")}if(currentYear+1>endYear){this.widget.find(".datepicker-months th:eq(2)").addClass("disabled")}for(var i=0;i<12;i++){if(year==startYear&&startMonth>i||year<startYear){$(months[i]).addClass("disabled")}else if(year==endYear&&endMonth<i||year>endYear){$(months[i]).addClass("disabled")}}html="";year=parseInt(year/10,10)*10;var yearCont=this.widget.find(".datepicker-years").find("th:eq(1)").text(year+"-"+(year+9)).end().find("td");this.widget.find(".datepicker-years").find("th").removeClass("disabled");if(startYear>year){this.widget.find(".datepicker-years").find("th:eq(0)").addClass("disabled")}if(endYear<year+9){this.widget.find(".datepicker-years").find("th:eq(2)").addClass("disabled")}year-=1;for(var i=-1;i<11;i++){html+='<span class="year'+(i===-1||i===10?" old":"")+(currentYear===year?" active":"")+(year<startYear||year>endYear?" disabled":"")+'">'+year+"</span>";year+=1}yearCont.html(html)},fillHours:function(){var table=this.widget.find(".timepicker .timepicker-hours table");table.parent().hide();var html="";if(this.options.pick12HourFormat){var current=1;for(var i=0;i<3;i+=1){html+="<tr>";for(var j=0;j<4;j+=1){var c=current.toString();html+='<td class="hour">'+padLeft(c,2,"0")+"</td>";current++}html+="</tr>"}}else{var current=0;for(var i=0;i<6;i+=1){html+="<tr>";for(var j=0;j<4;j+=1){var c=current.toString();html+='<td class="hour">'+padLeft(c,2,"0")+"</td>";current++}html+="</tr>"}}table.html(html)},fillMinutes:function(){var table=this.widget.find(".timepicker .timepicker-minutes table");table.parent().hide();var html="";var current=0;for(var i=0;i<5;i++){html+="<tr>";for(var j=0;j<4;j+=1){var c=current.toString();html+='<td class="minute">'+padLeft(c,2,"0")+"</td>";current+=3}html+="</tr>"}table.html(html)},fillSeconds:function(){var table=this.widget.find(".timepicker .timepicker-seconds table");table.parent().hide();var html="";var current=0;for(var i=0;i<5;i++){html+="<tr>";for(var j=0;j<4;j+=1){var c=current.toString();html+='<td class="second">'+padLeft(c,2,"0")+"</td>";current+=3}html+="</tr>"}table.html(html)},fillTime:function(){if(!this._date)return;var timeComponents=this.widget.find(".timepicker span[data-time-component]");var table=timeComponents.closest("table");var is12HourFormat=this.options.pick12HourFormat;var hour=this._date.getUTCHours();var period="AM";if(is12HourFormat){if(hour>=12)period="PM";if(hour===0)hour=12;else if(hour!=12)hour=hour%12;this.widget.find(".timepicker [data-action=togglePeriod]").text(period)}hour=padLeft(hour.toString(),2,"0");var minute=padLeft(this._date.getUTCMinutes().toString(),2,"0");var second=padLeft(this._date.getUTCSeconds().toString(),2,"0");timeComponents.filter("[data-time-component=hours]").text(hour);timeComponents.filter("[data-time-component=minutes]").text(minute);timeComponents.filter("[data-time-component=seconds]").text(second)},click:function(e){e.stopPropagation();e.preventDefault();this._unset=false;var target=$(e.target).closest("span, td, th");if(target.length===1){if(!target.is(".disabled")){switch(target[0].nodeName.toLowerCase()){case"th":switch(target[0].className){case"switch":this.showMode(1);break;case"prev":case"next":var vd=this.viewDate;var navFnc=DPGlobal.modes[this.viewMode].navFnc;var step=DPGlobal.modes[this.viewMode].navStep;if(target[0].className==="prev")step=step*-1;vd["set"+navFnc](vd["get"+navFnc]()+step);this.fillDate();this.set();break}break;case"span":if(target.is(".month")){var month=target.parent().find("span").index(target);this.viewDate.setUTCMonth(month)}else{var year=parseInt(target.text(),10)||0;this.viewDate.setUTCFullYear(year)}if(this.viewMode!==0){this._date=UTCDate(this.viewDate.getUTCFullYear(),this.viewDate.getUTCMonth(),this.viewDate.getUTCDate(),this._date.getUTCHours(),this._date.getUTCMinutes(),this._date.getUTCSeconds(),this._date.getUTCMilliseconds());this.notifyChange()}this.showMode(-1);this.fillDate();this.set();break;case"td":if(target.is(".day")){var day=parseInt(target.text(),10)||1;var month=this.viewDate.getUTCMonth();var year=this.viewDate.getUTCFullYear();if(target.is(".old")){if(month===0){month=11;year-=1}else{month-=1}}else if(target.is(".new")){if(month==11){month=0;year+=1}else{month+=1}}this._date=UTCDate(year,month,day,this._date.getUTCHours(),this._date.getUTCMinutes(),this._date.getUTCSeconds(),this._date.getUTCMilliseconds());this.viewDate=UTCDate(year,month,Math.min(28,day),0,0,0,0);this.fillDate();this.set();this.notifyChange()}break}}}},actions:{incrementHours:function(e){this._date.setUTCHours(this._date.getUTCHours()+1)},incrementMinutes:function(e){this._date.setUTCMinutes(this._date.getUTCMinutes()+1)},incrementSeconds:function(e){this._date.setUTCSeconds(this._date.getUTCSeconds()+1)},decrementHours:function(e){this._date.setUTCHours(this._date.getUTCHours()-1)},decrementMinutes:function(e){this._date.setUTCMinutes(this._date.getUTCMinutes()-1)},decrementSeconds:function(e){this._date.setUTCSeconds(this._date.getUTCSeconds()-1)},togglePeriod:function(e){var hour=this._date.getUTCHours();if(hour>=12)hour-=12;else hour+=12;this._date.setUTCHours(hour)},showPicker:function(){this.widget.find(".timepicker > div:not(.timepicker-picker)").hide();this.widget.find(".timepicker .timepicker-picker").show()},showHours:function(){this.widget.find(".timepicker .timepicker-picker").hide();this.widget.find(".timepicker .timepicker-hours").show()},showMinutes:function(){this.widget.find(".timepicker .timepicker-picker").hide();this.widget.find(".timepicker .timepicker-minutes").show()},showSeconds:function(){this.widget.find(".timepicker .timepicker-picker").hide();this.widget.find(".timepicker .timepicker-seconds").show()},selectHour:function(e){var tgt=$(e.target);var value=parseInt(tgt.text(),10);if(this.options.pick12HourFormat){var current=this._date.getUTCHours();if(current>=12){if(value!=12)value=(value+12)%24}else{if(value===12)value=0;else value=value%12}}this._date.setUTCHours(value);this.actions.showPicker.call(this)},selectMinute:function(e){var tgt=$(e.target);var value=parseInt(tgt.text(),10);this._date.setUTCMinutes(value);this.actions.showPicker.call(this)},selectSecond:function(e){var tgt=$(e.target);var value=parseInt(tgt.text(),10);this._date.setUTCSeconds(value);this.actions.showPicker.call(this)}},doAction:function(e){e.stopPropagation();e.preventDefault();if(!this._date)this._date=UTCDate(1970,0,0,0,0,0,0);var action=$(e.currentTarget).data("action");var rv=this.actions[action].apply(this,arguments);this.set();this.fillTime();this.notifyChange();return rv},stopEvent:function(e){e.stopPropagation();e.preventDefault()},keydown:function(e){var self=this,k=e.which,input=$(e.target);if(k==8||k==46){setTimeout(function(){self._resetMaskPos(input)})}},keypress:function(e){var k=e.which;if(k==8||k==46){return}var input=$(e.target);var c=String.fromCharCode(k);var val=input.val()||"";val+=c;var mask=this._mask[this._maskPos];if(!mask){return false}if(mask.end!=val.length){return}if(!mask.pattern.test(val.slice(mask.start))){val=val.slice(0,val.length-1);while((mask=this._mask[this._maskPos])&&mask.character){val+=mask.character;this._maskPos++}val+=c;if(mask.end!=val.length){input.val(val);return false}else{if(!mask.pattern.test(val.slice(mask.start))){input.val(val.slice(0,mask.start));return false}else{input.val(val);this._maskPos++;return false}}}else{this._maskPos++}},change:function(e){var input=$(e.target);var val=input.val();if(this._formatPattern.test(val)){this.update();this.setValue(this._date.getTime());this.notifyChange();this.set()}else if(val&&val.trim()){this.setValue(this._date.getTime());if(this._date)this.set();else input.val("")}else{if(this._date){this.setValue(null);this.notifyChange();this._unset=true}}this._resetMaskPos(input)},showMode:function(dir){if(dir){this.viewMode=Math.max(this.minViewMode,Math.min(2,this.viewMode+dir))}this.widget.find(".datepicker > div").hide().filter(".datepicker-"+DPGlobal.modes[this.viewMode].clsName).show()},destroy:function(){this._detachDatePickerEvents();this._detachDatePickerGlobalEvents();this.widget.remove();this.$element.removeData("datetimepicker");this.component.removeData("datetimepicker")},formatDate:function(d){return this.format.replace(formatReplacer,function(match){var methodName,property,rv,len=match.length;if(match==="ms")len=1;property=dateFormatComponents[match].property;if(property==="Hours12"){rv=d.getUTCHours();if(rv===0)rv=12;else if(rv!==12)rv=rv%12}else if(property==="Period12"){if(d.getUTCHours()>=12)return"PM";else return"AM"}else{methodName="get"+property;rv=d[methodName]()}if(methodName==="getUTCMonth")rv=rv+1;if(methodName==="getUTCYear")rv=rv+1900-2e3;return padLeft(rv.toString(),len,"0")})},parseDate:function(str){var match,i,property,methodName,value,parsed={};if(!(match=this._formatPattern.exec(str)))return null;for(i=1;i<match.length;i++){property=this._propertiesByIndex[i];if(!property)continue;value=match[i];if(/^\d+$/.test(value))value=parseInt(value,10);parsed[property]=value}return this._finishParsingDate(parsed)},_resetMaskPos:function(input){var val=input.val();for(var i=0;i<this._mask.length;i++){if(this._mask[i].end>val.length){this._maskPos=i;break}else if(this._mask[i].end===val.length){this._maskPos=i+1;break}}},_finishParsingDate:function(parsed){var year,month,date,hours,minutes,seconds,milliseconds;year=parsed.UTCFullYear;if(parsed.UTCYear)year=2e3+parsed.UTCYear;if(!year)year=1970;if(parsed.UTCMonth)month=parsed.UTCMonth-1;else month=0;date=parsed.UTCDate||1;hours=parsed.UTCHours||0;minutes=parsed.UTCMinutes||0;seconds=parsed.UTCSeconds||0;milliseconds=parsed.UTCMilliseconds||0;if(parsed.Hours12){hours=parsed.Hours12}if(parsed.Period12){if(/pm/i.test(parsed.Period12)){if(hours!=12)hours=(hours+12)%24}else{hours=hours%12}}return UTCDate(year,month,date,hours,minutes,seconds,milliseconds)},_compileFormat:function(){var match,component,components=[],mask=[],str=this.format,propertiesByIndex={},i=0,pos=0;while(match=formatComponent.exec(str)){component=match[0];if(component in dateFormatComponents){i++;propertiesByIndex[i]=dateFormatComponents[component].property;components.push("\\s*"+dateFormatComponents[component].getPattern(this)+"\\s*");mask.push({pattern:new RegExp(dateFormatComponents[component].getPattern(this)),property:dateFormatComponents[component].property,start:pos,end:pos+=component.length})}else{components.push(escapeRegExp(component));mask.push({pattern:new RegExp(escapeRegExp(component)),character:component,start:pos,end:++pos})}str=str.slice(component.length)}this._mask=mask;this._maskPos=0;this._formatPattern=new RegExp("^\\s*"+components.join("")+"\\s*$");this._propertiesByIndex=propertiesByIndex},_attachDatePickerEvents:function(){var self=this;this.widget.on("click",".datepicker *",$.proxy(this.click,this));this.widget.on("click","[data-action]",$.proxy(this.doAction,this));this.widget.on("mousedown",$.proxy(this.stopEvent,this));if(this.pickDate&&this.pickTime){this.widget.on("click.togglePicker",".accordion-toggle",function(e){e.stopPropagation();var $this=$(this);var $parent=$this.closest("ul");var expanded=$parent.find(".collapse.in");var closed=$parent.find(".collapse:not(.in)");if(expanded&&expanded.length){var collapseData=expanded.data("collapse");if(collapseData&&collapseData.transitioning)return;expanded.collapse("hide");closed.collapse("show");$this.find("i").toggleClass(self.timeIcon+" "+self.dateIcon);self.$element.find(".add-on i").toggleClass(self.timeIcon+" "+self.dateIcon)}})}if(this.isInput){this.$element.on({focus:$.proxy(this.show,this),change:$.proxy(this.change,this)});if(this.options.maskInput){this.$element.on({keydown:$.proxy(this.keydown,this),keypress:$.proxy(this.keypress,this)})}}else{this.$element.on({change:$.proxy(this.change,this)},"input");if(this.options.maskInput){this.$element.on({keydown:$.proxy(this.keydown,this),keypress:$.proxy(this.keypress,this)},"input")}if(this.component){this.component.on("click",$.proxy(this.show,this))}else{this.$element.on("click",$.proxy(this.show,this))}}},_attachDatePickerGlobalEvents:function(){$(window).on("resize.datetimepicker"+this.id,$.proxy(this.place,this));if(!this.isInput){$(document).on("mousedown.datetimepicker"+this.id,$.proxy(this.hide,this))}},_detachDatePickerEvents:function(){this.widget.off("click",".datepicker *",this.click);this.widget.off("click","[data-action]");this.widget.off("mousedown",this.stopEvent);if(this.pickDate&&this.pickTime){this.widget.off("click.togglePicker")}if(this.isInput){this.$element.off({focus:this.show,change:this.change});if(this.options.maskInput){this.$element.off({keydown:this.keydown,keypress:this.keypress})}}else{this.$element.off({change:this.change},"input");if(this.options.maskInput){this.$element.off({keydown:this.keydown,keypress:this.keypress},"input")}if(this.component){this.component.off("click",this.show)}else{this.$element.off("click",this.show)}}},_detachDatePickerGlobalEvents:function(){$(window).off("resize.datetimepicker"+this.id);if(!this.isInput){$(document).off("mousedown.datetimepicker"+this.id)}},_isInFixed:function(){if(this.$element){var parents=this.$element.parents();var inFixed=false;for(var i=0;i<parents.length;i++){if($(parents[i]).css("position")=="fixed"){inFixed=true;break}}return inFixed}else{return false}}};$.fn.datetimepicker=function(option,val){return this.each(function(){var $this=$(this),data=$this.data("datetimepicker"),options=typeof option==="object"&&option;if(!data){$this.data("datetimepicker",data=new DateTimePicker(this,$.extend({},$.fn.datetimepicker.defaults,options)))}if(typeof option==="string")data[option](val)})};$.fn.datetimepicker.defaults={maskInput:false,pickDate:true,pickTime:true,pick12HourFormat:false,pickSeconds:true,startDate:-Infinity,endDate:Infinity,collapse:true};$.fn.datetimepicker.Constructor=DateTimePicker;var dpgId=0;var dates=$.fn.datetimepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}};var dateFormatComponents={dd:{property:"UTCDate",getPattern:function(){return"(0?[1-9]|[1-2][0-9]|3[0-1])\\b"}},MM:{property:"UTCMonth",getPattern:function(){return"(0?[1-9]|1[0-2])\\b"}},yy:{property:"UTCYear",getPattern:function(){return"(\\d{2})\\b"}},yyyy:{property:"UTCFullYear",getPattern:function(){return"(\\d{4})\\b"}},hh:{property:"UTCHours",getPattern:function(){return"(0?[0-9]|1[0-9]|2[0-3])\\b"}},mm:{property:"UTCMinutes",getPattern:function(){return"(0?[0-9]|[1-5][0-9])\\b"}},ss:{property:"UTCSeconds",getPattern:function(){return"(0?[0-9]|[1-5][0-9])\\b"}},ms:{property:"UTCMilliseconds",getPattern:function(){return"([0-9]{1,3})\\b"}},HH:{property:"Hours12",getPattern:function(){return"(0?[1-9]|1[0-2])\\b"}},PP:{property:"Period12",getPattern:function(){return"(AM|PM|am|pm|Am|aM|Pm|pM)\\b"}}};var keys=[];for(var k in dateFormatComponents)keys.push(k);keys[keys.length-1]+="\\b";keys.push(".");var formatComponent=new RegExp(keys.join("\\b|"));keys.pop();var formatReplacer=new RegExp(keys.join("\\b|"),"g");function escapeRegExp(str){return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}function padLeft(s,l,c){if(l<s.length)return s;else return Array(l-s.length+1).join(c||" ")+s}function getTemplate(timeIcon,pickDate,pickTime,is12Hours,showSeconds,collapse){if(pickDate&&pickTime){return'<div class="bootstrap-datetimepicker-widget dropdown-menu">'+"<ul>"+"<li"+(collapse?' class="collapse in"':"")+">"+'<div class="datepicker">'+DPGlobal.template+"</div>"+"</li>"+'<li class="picker-switch accordion-toggle"><a><i class="'+timeIcon+'"></i></a></li>'+"<li"+(collapse?' class="collapse"':"")+">"+'<div class="timepicker">'+TPGlobal.getTemplate(is12Hours,showSeconds)+"</div>"+"</li>"+"</ul>"+"</div>"}else if(pickTime){return'<div class="bootstrap-datetimepicker-widget dropdown-menu">'+'<div class="timepicker">'+TPGlobal.getTemplate(is12Hours,showSeconds)+"</div>"+"</div>"}else{return'<div class="bootstrap-datetimepicker-widget dropdown-menu">'+'<div class="datepicker">'+DPGlobal.template+"</div>"+"</div>"}}function UTCDate(){return new Date(Date.UTC.apply(Date,arguments))}var DPGlobal={modes:[{clsName:"days",navFnc:"UTCMonth",navStep:1},{clsName:"months",navFnc:"UTCFullYear",navStep:1},{clsName:"years",navFnc:"UTCFullYear",navStep:10}],isLeapYear:function(year){return year%4===0&&year%100!==0||year%400===0},getDaysInMonth:function(year,month){return[31,DPGlobal.isLeapYear(year)?29:28,31,30,31,30,31,31,30,31,30,31][month]},headTemplate:"<thead>"+"<tr>"+'<th class="prev">‹</th>'+'<th colspan="5" class="switch"></th>'+'<th class="next">›</th>'+"</tr>"+"</thead>",contTemplate:'<tbody><tr><td colspan="7"></td></tr></tbody>'};DPGlobal.template='<div class="datepicker-days">'+'<table class="table-condensed">'+DPGlobal.headTemplate+"<tbody></tbody>"+"</table>"+"</div>"+'<div class="datepicker-months">'+'<table class="table-condensed">'+DPGlobal.headTemplate+DPGlobal.contTemplate+"</table>"+"</div>"+'<div class="datepicker-years">'+'<table class="table-condensed">'+DPGlobal.headTemplate+DPGlobal.contTemplate+"</table>"+"</div>";var TPGlobal={hourTemplate:'<span data-action="showHours" data-time-component="hours" class="timepicker-hour"></span>',minuteTemplate:'<span data-action="showMinutes" data-time-component="minutes" class="timepicker-minute"></span>',secondTemplate:'<span data-action="showSeconds" data-time-component="seconds" class="timepicker-second"></span>'};TPGlobal.getTemplate=function(is12Hours,showSeconds){return'<div class="timepicker-picker">'+'<table class="table-condensed"'+(is12Hours?' data-hour-format="12"':"")+">"+"<tr>"+'<td><a href="#" class="btn" data-action="incrementHours"><i class="icon-chevron-up"></i></a></td>'+'<td class="separator"></td>'+'<td><a href="#" class="btn" data-action="incrementMinutes"><i class="icon-chevron-up"></i></a></td>'+(showSeconds?'<td class="separator"></td>'+'<td><a href="#" class="btn" data-action="incrementSeconds"><i class="icon-chevron-up"></i></a></td>':"")+(is12Hours?'<td class="separator"></td>':"")+"</tr>"+"<tr>"+"<td>"+TPGlobal.hourTemplate+"</td> "+'<td class="separator">:</td>'+"<td>"+TPGlobal.minuteTemplate+"</td> "+(showSeconds?'<td class="separator">:</td>'+"<td>"+TPGlobal.secondTemplate+"</td>":"")+(is12Hours?'<td class="separator"></td>'+"<td>"+'<button type="button" class="btn btn-primary" data-action="togglePeriod"></button>'+"</td>":"")+"</tr>"+"<tr>"+'<td><a href="#" class="btn" data-action="decrementHours"><i class="icon-chevron-down"></i></a></td>'+'<td class="separator"></td>'+'<td><a href="#" class="btn" data-action="decrementMinutes"><i class="icon-chevron-down"></i></a></td>'+(showSeconds?'<td class="separator"></td>'+'<td><a href="#" class="btn" data-action="decrementSeconds"><i class="icon-chevron-down"></i></a></td>':"")+(is12Hours?'<td class="separator"></td>':"")+"</tr>"+"</table>"+"</div>"+'<div class="timepicker-hours" data-action="selectHour">'+'<table class="table-condensed">'+"</table>"+"</div>"+'<div class="timepicker-minutes" data-action="selectMinute">'+'<table class="table-condensed">'+"</table>"+"</div>"+(showSeconds?'<div class="timepicker-seconds" data-action="selectSecond">'+'<table class="table-condensed">'+"</table>"+"</div>":"")}})(window.jQuery); \ No newline at end of file Copied: trunk/pollen-ui-angular/src/main/webapp/js/libs/jquery.scrollto.js (from rev 3869, trunk/pollen-ui-js/src/main/webapp/js/libs/jquery.scrollto.js) =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/js/libs/jquery.scrollto.js (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/js/libs/jquery.scrollto.js 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,54 @@ +/* + * #%L + * Pollen :: UI (JS) + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2013 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +/*! + * jquery.scrollto.js 0.0.1 - https://github.com/yckart/jquery.scrollto.js + * Scroll smooth to any element in your DOM. + * + * Copyright (c) 2012 Yannick Albert (http://yckart.com) + * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php). + * 2013/02/17 + **/ +$.scrollTo = $.fn.scrollTo = function(x, y, options){ + if (!(this instanceof $)) return $.fn.scrollTo.apply($('html, body'), arguments); + + options = $.extend({}, { + gap: { + x: 0, + y: 0 + }, + animation: { + easing: 'swing', + duration: 600, + complete: $.noop, + step: $.noop + } + }, options); + + return this.each(function(){ + var elem = $(this); + elem.stop().animate({ + scrollLeft: !isNaN(Number(x)) ? x : $(y).offset().left + options.gap.x, + scrollTop: !isNaN(Number(y)) ? y : $(y).offset().top + options.gap.y + }, options.animation); + }); +}; Added: trunk/pollen-ui-angular/src/main/webapp/js/services.js =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/js/services.js (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/js/services.js 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,4 @@ +angular.module('pollenServices', ['ngResource']).factory('Poll', function($resource) { + return $resource('http://localhost:8080/pollen/v1/polls/:pollId', {}, { + }); +}); \ No newline at end of file Added: trunk/pollen-ui-angular/src/main/webapp/partials/home.html =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/partials/home.html (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/partials/home.html 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,3 @@ +<div class="hero-unit"> + <img src="../img/pollen.png"/> +</div> \ No newline at end of file Added: trunk/pollen-ui-angular/src/main/webapp/partials/poll-detail.html =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/partials/poll-detail.html (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/partials/poll-detail.html 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,166 @@ +<div class="page-header"> + + <h1>{{ poll.title }}</h1> + + <p> + {{ poll.creator.name }} + <!-- number of votes --> + | <a id="voteSummary" class='link'><i class='icon-user'></i> {{ votes.length }}</a> + <!-- number of comments--> + | <a id="commentSummary" class='link'><i class='icon-comment'></i> {{ comments.length }}</a> + <!--<!– poll dates –>--> + <!--<% if (poll.attr('beginDate') && poll.attr('endDate')) { %>--> + <!--| <i class='icon-time'></i> <%= pollen.common.date.fromTo(moment(poll.attr('beginDate')).format(pollen.common.format.dateTime.moment), moment(poll.attr('endDate')).format(pollen.common.format.dateTime.moment)) %>--> + <!--<% } else if (poll.attr('beginDate')) { %>--> + <!--| <i class='icon-time'></i> <%= pollen.common.date.from(moment(poll.attr('beginDate')).format(pollen.common.format.dateTime.moment)) %>--> + <!--<% } else if (poll.attr('endDate')) { %>--> + <!--| <i class='icon-time'></i> <%= pollen.common.date.to(moment(poll.attr('endDate')).format(pollen.common.format.dateTime.moment)) %>--> + <!--<% } %>--> + </p> + + <p>{{ poll.description }}</p> + +</div> + +<!-- alert if the poll is closed --> +<div ng-show="poll.closed" class="alert fade in"> + <button type="button" class="close" data-dismiss="alert">×</button> + <%== pollen.vote.poll.closed.alert %> +</div> + +<!-- list of the choices --> +<div class='well'> + + <h3><%= pollen.vote.choices.list.title %></h3> + + <ol> + <li ng-repeat="choice in choices"><strong>{{ choice.name }}</strong> : + {{ choice.description }} <em ng-show="!choice.description"> <%= pollen.choice.noDescription %></em></li> + </ol> + + <div ng-show="poll.choiceAddAllowed && poll.beginChoiceDate <= moment().valueOf() && poll.endChoiceDate > moment().valueOf()"> + + <!-- link to show/hide the new choice form --> + <button class="collapsed btn btn-link" data-toggle="collapse" data-target="#addChoiceForm"> + <%= pollen.vote.choices.list.button.addChoice %> <i class="icon-collapse"></i> + </button> + + <!-- form to add a new choice to the poll --> + <form id="addChoiceForm" class="collapse form-horizontal"> + <div class="control-group"> + <label class="control-label" ><%= pollen.choice.name.placeholder %></label> + <div class="controls"> + <input type="text" name="name" placeholder="<%= pollen.choice.name.placeholder %>"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" ><%= pollen.choice.description.placeholder %></label> + <div class="controls"> + <textarea name="description" placeholder="<%= pollen.choice.description.placeholder %>"></textarea> + </div> + </div> + <div class="control-group"> + <div class="controls"> + <button type="submit" class="btn btn-primary"><%= pollen.common.validate %></button> + </div> + </div> + </form> + </div> +</div> + +<!-- table of the votes --> +<form id="voteForm"> + + <h2><%= pollen.vote.votes.list.title %></h2> + + <table id="voteTable" class="table table-bordered table-striped"> + <thead> + <tr> + <th><%= pollen.vote.votes.list.header.voter %></th> + <th ng-repeat="choice in choices" data-container='body' data-placement='top' title='{{ choice.description }}'> + {{ choice.name }} + </th> + </tr> + </thead> + <tbody> + <tr ng-repeat="vote in votes" > + <td>{{ vote.voterListMember.name }}</td> + <td ng-repeat="choice in choices" ng-init="voteChoice = vote.voteToChoices[choice.id]"> + <div ng-hide="voteChoice" class='choice voteBeforeChoice'></div> + <div ng-show="voteChoice" ng-class='[choice, voteChoice.voteValue : selected]'> + <span ng-show="voteChoice.voteValue">OK</span> + </div> + </td> + </tr> + + <tr> + <td>Resultats</td> + <td ng-repeat="choice in choices" class='result'> + {{ poll.results[choice.id] }} + </td> + </tr> + + <tr ng-hide="poll.closed"> + <td> + <div class="control-group"> + <div class="controls"> + <input name="userName" + type='text' + value='{{ currentUser.name }}' + placeholder='<%= pollen.vote.form.add.field.userName.placeholder %>' + required/> + </div> + </div> + </td> + <td ng-repeat="choice in choices"><input name="{{ $index }}" type='checkbox'/></td> + </tr> + </tbody> + </table> + + <div ng-hide="poll.closed" class="form-actions"> + <button type="submit" id="voteButton" class="btn btn-primary"><%= pollen.vote.form.add.button.vote %></button> + </div> + +</form> + +<!-- Comments --> +<div id="comments"> + <h2><%= pollen.vote.comments.list.title %></h2> + + <button class="collapsed btn btn-link" data-toggle="collapse" data-target="#addCommentForm"> + <%= pollen.vote.comments.list.button.addComment %> <i class="icon-collapse"></i> + </button> + + <form id="addCommentForm" ng-submit="addComment()" class="collapse form-horizontal"> + <div class="control-group"> + <label class="control-label" ><%= pollen.vote.comments.add.field.userName.placeholder %></label> + <div class="controls"> + <input type="text" name="author" ng-model="author" placeholder="<%= pollen.vote.comments.add.field.userName.placeholder %>"/> + </div> + </div> + <div class="control-group"> + <label class="control-label" ><%= pollen.vote.comments.add.field.message.placeholder %></label> + <div class="controls"> + <textarea name="text" ng-model="text" placeholder="<%= pollen.vote.comments.add.field.message.placeholder %>"></textarea> + </div> + </div> + <div class="control-group"> + <div class="controls"> + <button type="submit" class="btn btn-primary"><%= pollen.common.validate %></button> + </div> + </div> + </form> + + <div class='list alternate-colors'> + + <div ng-repeat="comment in comments"> + <p> + {{ comment.text }} + </p> + <div class='footer'> + <small>{{ comment.author }} | {{ moment(comment.postDate).format(pollen.common.format.dateTime.moment) }}</small> + </div> + </div> + + </div> +</div> \ No newline at end of file Added: trunk/pollen-ui-angular/src/main/webapp/partials/poll-form.html =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/partials/poll-form.html (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/partials/poll-form.html 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,325 @@ +<h1>pollen.poll.form.create.title</h1> + +<ul class="breadcrumb"> + <li ng-class='{ active : step >= 1 }' step="1"><span class='step'>pollen.poll.form.create.step1</span> <span class="divider">/</span></li> + <li ng-class='{ active : step >= 2 }' step="2"><span class='step'>pollen.poll.form.create.step2</span> <span class="divider">/</span></li> + <li ng-class='{ active : step >= 3 }' step="3"><span class='step'>pollen.poll.form.create.step3</span> <span class="divider">/</span></li> +</ul> + +<form id='pollCreationForm' class="form-horizontal"> + + <!-- Basic info step --> + <div class='step1' ng-show="step == 1"> + <h3>pollen.poll.form.create.step1</h3> + + <div class="control-group"> + <label class="control-label" for="pollCreationFormTitle">pollen.poll.title.label</label> + <div class="controls"> + <input type='text' name='title' id='pollCreationFormTitle' class="input-xxlarge" + placeholder='pollen.poll.title.placeholder' + ng-model='poll.title'/> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for='pollCreationFormDescription'>pollen.poll.description.label</label> + <div class="controls"> + <textarea id='pollCreationFormDescription' class="input-xxlarge" + name='description' + placeholder="pollen.poll.description.placeholder" + ng-model="poll.description"></textarea> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for='pollCreationFormCreatorName'>pollen.poll.creator.name.label</label> + <div class="controls"> + <input type='text' name='creator.name' id='pollCreationFormCreatorName' class="input-xxlarge" + placeholder='pollen.poll.creator.name.placeholder' + ng-model='poll.creator.name'/> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for='pollCreationFormCreatorEmail'>pollen.poll.creator.email.label</label> + <div class="controls"> + <input type='text' name='creator.email' id='pollCreationFormCreatorEmail' class="input-xxlarge" + placeholder='pollen.poll.creator.email.placeholder' + ng-model='poll.creator.email'/> + </div> + </div> + + <div class="form-actions"> + <button type="button" class="btn nextStep" ng-click="next()">pollen.poll.form.create.button.next</button> + </div> + </div> + + <!-- choices step --> + <div class='step2' ng-show="step == 2"> + <h3>pollen.poll.form.create.step2</h3> + + <div class="control-group row-fluid" ng-repeat="choice in poll.choices"> + <label class="control-label span1" for='pollCreationFormCreatorName'>pollen.poll.choice.name.label</label> + <div class="controls span3"> + <input type='text' name='name' class="input-block-level" + placeholder='pollen.poll.choice.name.placeholder' + ng-model="choice.name"/> + </div> + + <label class="control-label span1" for='pollCreationFormCreatorName'>pollen.poll.choice.description.label</label> + <div class="controls span7"> + <textarea name='description' class="input-block-level" + placeholder="pollen.poll.choice.description.placeholder" + ng-model="choice.description"></textarea> + </div> + </div> + + <div class="form-actions"> + <button type="button" class="btn prevStep" ng-click="prev()">pollen.poll.form.create.button.previous</button> + <button type='button' class='btn addChoice' ng-click="addChoice()">pollen.poll.form.create.button.addChoice</button> + <button type='submit' class="btn btn-primary">pollen.poll.form.create.button.save</button> + <button type="button" class="btn nextStep" ng-click="next()">pollen.poll.form.create.button.next</button> + </div> + + </div> + + <!-- Options step --> + <div class='step3' ng-show="step == 3"> + + <h3>pollen.poll.form.create.step3</h3> + + <!-- dates --> + <fieldset> + <legend>pollen.poll.form.create.legend.validityDates</legend> + + <div class="control-group"> + <label class="control-label" for='pollCreationFormBeginDate'>pollen.poll.beginDate.label</label> + <div class="controls"> + <div class="input-append dateTimePicker"> + <input type="text" name='beginDate' id='pollCreationFormBeginDate' + placeholder='pollen.poll.beginDate.placeholder' + value='<%= poll.attr("beginDate") ? moment(poll.attr("beginDate")).format(pollen.common.format.dateTime.moment) : "" %>'/> + <span class="add-on"> + <i data-time-icon="icon-time" data-date-icon="icon-calendar"></i> + </span> + </div> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for='pollCreationFormEndDate'>pollen.poll.endDate.label</label> + <div class="controls"> + <div class="input-append dateTimePicker"> + <input type="text" name='endDate' id='pollCreationFormEndDate' + placeholder='<%= pollen.poll.endDate.placeholder %>' + value='<%= poll.attr("endDate") ? moment(poll.attr("endDate")).format(pollen.common.format.dateTime.moment) : "" %>'/> + <span class="add-on"> + <i data-time-icon="icon-time" data-date-icon="icon-calendar"></i> + </span> + </div> + </div> + </div> + + </fieldset> + + <!-- choices --> + <fieldset> + <legend>pollen.poll.form.create.legend.choices</legend> + + <div class="control-group"> + <div class="controls"> + <label class="checkbox"> + <input type="checkbox" id='pollCreationFormChoiceAddAllowed' name="choiceAddAllowed" + ng-model="poll.choiceAddAllowed"/> + pollen.poll.choiceAddAllowed.label + </label> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for='pollCreationFormAddChoiceBeginDate'>pollen.poll.addChoiceBeginDate.label</label> + <div class="controls"> + <div class="input-append dateTimePicker addChoiceDate"> + <input type="text" name='addChoiceBeginDate' id='pollCreationFormAddChoiceBeginDate' + placeholder='pollen.poll.addChoiceBeginDate.placeholder' + value='<%= poll.attr("addChoiceBeginDate") ? moment(poll.attr("addChoiceBeginDate")).format(pollen.common.format.dateTime.moment) : "" %>'/> + <span class="add-on"> + <i data-time-icon="icon-time" data-date-icon="icon-calendar"></i> + </span> + </div> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for='pollCreationFormAddChoiceEndDate'>pollen.poll.addChoiceEndDate.label</label> + <div class="controls"> + <div class="input-append dateTimePicker addChoiceDate"> + <input type="text" name='addChoiceEndDate' id='pollCreationFormAddChoiceEndDate' + placeholder='<%= pollen.poll.addChoiceEndDate.placeholder %>' + value='<%= poll.attr("addChoiceEndDate") ? moment(poll.attr("addChoiceEndDate")).format(pollen.common.format.dateTime.moment) : "" %>'/> + <span class="add-on"> + <i data-time-icon="icon-time" data-date-icon="icon-calendar"></i> + </span> + </div> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for='pollCreationFormMaxChoiceNumber'>pollen.poll.maxChoiceNumber.label</label> + <div class="controls"> + <input type='number' name='maxChoiceNumber' id='pollCreationFormMaxChoiceNumber' class="input-mini" + placeholder='<%= pollen.poll.maxChoiceNumber.placeholder %>' + ng-model='poll.maxChoiceNumber'/> + <span class="help-inline">pollen.poll.maxChoiceNumber.help</span> + </div> + </div> + + </fieldset> + + <!-- votes --> + <fieldset> + <legend>pollen.poll.form.create.legend.votes</legend> + + <div class="control-group"> + <label class="control-label" for="pollCreationFormCommentVisibility">pollen.poll.commentVisibility.label</label> + <div class="controls"> + <select name='commentVisibility' id='pollCreationFormCommentVisibility'> + <option value="EVERYBODY">pollen.poll.commentVisibility.everybody.label</option> + <option value="VOTER">pollen.poll.commentVisibility.voter.label</option> + <option value="NOBODY">pollen.poll.commentVisibility.nobody.label</option> + </select> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="pollCreationFormVoteVisibility">pollen.poll.voteVisibility.label</label> + <div class="controls"> + <select name='voteVisibility' id='pollCreationFormVoteVisibility'> + <option value="EVERYBODY">pollen.poll.voteVisibility.everybody.label</option> + <option value="VOTER">pollen.poll.voteVisibility.voter.label</option> + <option value="CREATOR">pollen.poll.voteVisibility.creator.label</option> + <option value="ANONYMOUS">pollen.poll.voteVisibility.anonymous.label</option> + </select> + </div> + </div> + + <div class="control-group"> + <div class="controls"> + <label class="checkbox"> + <input type="checkbox" id='pollCreationFormAnonymousVoteAllowed' name="anonymousVoteAllowed" + ng-model='poll.anonymousVoteAllowed'/> + pollen.poll.anonymousVoteAllowed.label + </label> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="pollCreationFormPollType">pollen.poll.pollType.label</label> + <div class="controls"> + <select name='pollType' id='pollCreationFormPollType'> + <option value="FREE">pollen.poll.pollType.free.label</option> + <option value="RESTRICTED">pollen.poll.pollType.restricted.label</option> + <option value="GROUP">pollen.poll.pollType.group.label</option> + </select> + </div> + </div> + + <% + if (poll.attr("pollType") == "RESTRICTED") { + poll.voterList[0].each(function(voter) { + %> + <div class="control-group row-fluid"> + <label class="control-label span1"><%= pollen.poll.voter.name.label %></label> + <div class="controls span3"> + <input type='text' name='name' class="input-block-level" + placeholder='<%= pollen.poll.voter.name.placeholder %>' + value="<%= voter.attr('name') %>" + <%= (el) -> el.data('owner', voter) %>/> + </div> + + <label class="control-label span1"><%= pollen.poll.voter.email.label %></label> + <div class="controls span4"> + <input type='text' name='email' class="input-block-level" + placeholder='<%= pollen.poll.voter.email.placeholder %>' + value="<%= voter.attr('email') %>" + <%= (el) -> el.data('owner', voter) %>/> + </div> + + <label class="control-label span1"><%= pollen.poll.voter.weight.label %></label> + <div class="controls span1"> + <input type='text' name='weight' class="input-block-level" + placeholder='<%= pollen.poll.voter.weight.placeholder %>' + value="<%= voter.attr('weight') %>" + <%= (el) -> el.data('owner', voter) %>/> + </div> + + <button type="button" class='btn btn-danger span1'><i class="icon-minus icon-white"></i></button> + </div> + <% }) %> + <button type="button" class='btn btn-success span1'><i class="icon-plus icon-white"></i></button> + <% } %> + + + </fieldset> + + <!-- results --> + <fieldset> + <legend>pollen.poll.form.create.legend.results</legend> + + <div class="control-group"> + <label class="control-label" for="pollCreationFormVoteCountingType"><%= pollen.poll.voteCountingType.label %></label> + <div class="controls"> + <select name='voteCountingType' id='pollCreationFormVoteCountingType' <%= (el) -> el.data('owner', poll) %>> + <option value="1" <%= (el) -> el.data('description', 'normal') %>><%= pollen.choice.voteType.normal.label %></option> + <option value="2" <%= (el) -> el.data('description', 'percentage') %>><%= pollen.choice.voteType.percentage.label %></option> + <option value="3" <%= (el) -> el.data('description', 'condorcet') %>><%= pollen.choice.voteType.condorcet.label %></option> + <option value="4" <%= (el) -> el.data('description', 'number') %>><%= pollen.choice.voteType.number.label %></option> + <option value="5" <%= (el) -> el.data('description', 'borda') %>><%= pollen.choice.voteType.borda.label %></option> + <option value="6" <%= (el) -> el.data('description', 'alternative') %>><%= pollen.choice.voteType.alternative.label %></option> + <option value="7" <%= (el) -> el.data('description', 'coombs') %>><%= pollen.choice.voteType.coombs.label %></option> + </select> + <span id='pollCreationFormVoteCountingTypeHelp' class="help-block">pollen.choice.voteType.normal.description</span> + </div> + </div> + + <div class="control-group"> + <label class="control-label" for="pollCreationFormResultVisibility">pollen.poll.resultVisibility.label</label> + <div class="controls"> + <select name='resultVisibility' id='pollCreationFormResultVisibility'> + <option value="EVERYBODY">pollen.poll.resultVisibility.everybody.label</option> + <option value="VOTER">pollen.poll.resultVisibility.voter.label</option> + <option value="CREATOR">pollen.poll.resultVisibility.creator.label</option> + </select> + </div> + </div> + + <div class="control-group"> + <div class="controls"> + <label class="checkbox"> + <input type="checkbox" id='pollCreationFormContinuousResults' name="continuousResults" + ng-model="poll.continuousResults"/> + pollen.poll.continuousResults.label + </label> + </div> + </div> + + </fieldset> + + + <div class="form-actions"> + <button type="button" class="btn prevStep" ng-click="prev()">pollen.poll.form.create.button.previous</button> + <button type='submit' class="btn btn-primary">pollen.poll.form.create.button.save</button> + </div> + </div> + +</form> + +<script> + /*$(function() { + $('.dateTimePicker').datetimepicker({ + language: 'fr_FR', + pickSeconds: false, + format: pollen.common.format.dateTime.input + }); + });*/ +</script> \ No newline at end of file Added: trunk/pollen-ui-angular/src/main/webapp/partials/poll-list.html =================================================================== --- trunk/pollen-ui-angular/src/main/webapp/partials/poll-list.html (rev 0) +++ trunk/pollen-ui-angular/src/main/webapp/partials/poll-list.html 2014-03-12 09:46:22 UTC (rev 3870) @@ -0,0 +1,14 @@ +<div class="container-fluid"> + <div class="row-fluid"> + <div class="span10"> + <!--Body content--> + + <ul class="polls"> + <li ng-repeat="poll in polls" class="thumbnail"> + <a href="#/polls/{{poll.id}}">{{poll.title}}</a> + </li> + </ul> + + </div> + </div> +</div> \ No newline at end of file Modified: trunk/pollen-ui-js/pom.xml =================================================================== --- trunk/pollen-ui-js/pom.xml 2014-02-17 07:06:51 UTC (rev 3869) +++ trunk/pollen-ui-js/pom.xml 2014-03-12 09:46:22 UTC (rev 3870) @@ -9,7 +9,7 @@ <version>2.0-SNAPSHOT</version> </parent> - <name>Pollen :: UI (JS) </name> + <name>Pollen :: UI (CanJS) </name> <description>Pollen UI</description> <groupId>org.chorem.pollen</groupId> Modified: trunk/pollen-ui-js/src/main/webapp/bundle/Messages.properties =================================================================== --- trunk/pollen-ui-js/src/main/webapp/bundle/Messages.properties 2014-02-17 07:06:51 UTC (rev 3869) +++ trunk/pollen-ui-js/src/main/webapp/bundle/Messages.properties 2014-03-12 09:46:22 UTC (rev 3870) @@ -58,7 +58,8 @@ pollen.poll.addChoiceEndDate.label=Date de fin d'ajout de choix pollen.poll.addChoiceEndDate.placeholder=Date de fin d'ajout de choix pollen.poll.maxChoiceNumber.label=Nombre limite de choix par vote -pollen.poll.maxChoiceNumber.placeholder=Laisser vide ou 0 pour ne pas fixer de limite +pollen.poll.maxChoiceNumber.placeholder=Nombre limite de choix par vote +pollen.poll.maxChoiceNumber.help=Laisser vide ou 0 pour ne pas fixer de limite pollen.poll.commentVisibility.label=Visibilité des commentaires pollen.poll.commentVisibility.everybody.label=Publique pollen.poll.commentVisibility.voter.label=Seulement les votants @@ -73,6 +74,12 @@ pollen.poll.pollType.free.label=Libre pollen.poll.pollType.restricted.label=Restreint pollen.poll.pollType.group.label=Groupe +pollen.poll.voter.name.label=Nom +pollen.poll.voter.name.placeholder=Nom +pollen.poll.voter.email.label=Email +pollen.poll.voter.email.placeholder=Email +pollen.poll.voter.weight.label=Poids +pollen.poll.voter.weight.placeholder=Poids pollen.poll.resultVisibility.label=Visibilité des résultats pollen.poll.resultVisibility.everybody.label=Publique pollen.poll.resultVisibility.voter.label=Seulement les votants @@ -130,11 +137,13 @@ #poll creation form pollen.poll.form.create.button.save=Créer le sondage +pollen.poll.form.create.button.previous=Précedent pollen.poll.form.create.button.next=Suivant pollen.poll.form.create.button.addChoice=Ajouter un choix -pollen.poll.form.create.field.title.label=Titre -pollen.poll.form.create.field.title.placeholder=Titre pollen.poll.form.create.title=Création de sondage +pollen.poll.form.create.step1=Informations générales +pollen.poll.form.create.step2=Définition des choix +pollen.poll.form.create.step3=Options pollen.poll.form.create.legend.validityDates=Plage de validité pollen.poll.form.create.legend.choices=Choix pollen.poll.form.create.legend.votes=Votes Modified: trunk/pollen-ui-js/src/main/webapp/css/style.css =================================================================== --- trunk/pollen-ui-js/src/main/webapp/css/style.css 2014-02-17 07:06:51 UTC (rev 3869) +++ trunk/pollen-ui-js/src/main/webapp/css/style.css 2014-03-12 09:46:22 UTC (rev 3870) @@ -85,10 +85,6 @@ color: rgb(150, 150, 150); } -#content > div { - display: none; -} - #voteForm .choice { background-position: center; background-repeat: no-repeat; Copied: trunk/pollen-ui-js/src/main/webapp/img/pollen.png (from rev 3821, branches/pollen-2.0/pollen-ui-struts2/src/main/webapp/img/pollen_fr.png) =================================================================== (Binary files differ) Modified: trunk/pollen-ui-js/src/main/webapp/js/controls/poll_form.js =================================================================== --- trunk/pollen-ui-js/src/main/webapp/js/controls/poll_form.js 2014-02-17 07:06:51 UTC (rev 3869) +++ trunk/pollen-ui-js/src/main/webapp/js/controls/poll_form.js 2014-03-12 09:46:22 UTC (rev 3870) @@ -22,14 +22,22 @@ */ var PollForm = can.Control({ - defaults: { - poll: new Poll({ choiceAddAllowed: true }), - choices: new Choice.List([{}, {}]), - process: new can.Observe({ - step: 1 - }) - } + defaults: { + poll: new Poll({ + choiceAddAllowed: true, + choice: [] + }), + process: new can.Observe({ + step: 1 + }) + }, + pollDefaultValues: { + continuousResults: true, + choice: [{},{}], + voterList: [[{}, {}]] + } + }, { init: function() { @@ -37,7 +45,6 @@ this.element.html(can.view('views/poll_form.ejs', { poll: this.options.poll, - choices: this.options.choices, process: this.options.process })); @@ -115,6 +122,11 @@ } }, + 'button.prevStep click': function() { + var process = this.options.process; + process.attr('step', process.step - 1); + }, + 'button.nextStep click': function() { var process = this.options.process; process.attr('step', process.step + 1); @@ -137,14 +149,12 @@ }, '.addChoice click': function() { - this.options.choices.push({}); + this.options.poll.choice.push({}); }, '#pollCreationForm submit': function(form) { var self = this; - this.options.poll.attr('choice', this.options.choices); - this.options.poll.save(function(data) { if (data.id) { self.options.poll.id = data.id; @@ -156,9 +166,10 @@ }, editPoll: function(poll) { - this.options.poll.attr(poll._data, true); + this.options.poll.attr(this.constructor.pollDefaultValues, true); + this.options.poll.attr(poll._data); this.element.siblings().hide(); - this.options.process.attr('step', 3); + this.options.process.attr('step', 1); this.element.show(); } Modified: trunk/pollen-ui-js/src/main/webapp/views/poll_form.ejs =================================================================== --- trunk/pollen-ui-js/src/main/webapp/views/poll_form.ejs 2014-02-17 07:06:51 UTC (rev 3869) +++ trunk/pollen-ui-js/src/main/webapp/views/poll_form.ejs 2014-03-12 09:46:22 UTC (rev 3870) @@ -1,19 +1,21 @@ <h1><%= pollen.poll.form.create.title %></h1> <ul class="breadcrumb"> - <li class='active' <%= (el) -> el.data('step', 1) %>><span class='step'>Step 1</span> <span class="divider">/</span></li> - <li <%= (el) -> el.data('step', 2) %>><span class='step'>Step 2</span> <span class="divider">/</span></li> -<li <%= (el) -> el.data('step', 3) %>><span class='step'>Step 3</span> <span class="divider">/</span></li> + <li class='active' <%= (el) -> el.data('step', 1) %>><span class='step'><%= pollen.poll.form.create.step1 %></span> <span class="divider">/</span></li> + <li <%= (el) -> el.data('step', 2) %>><span class='step'><%= pollen.poll.form.create.step2 %></span> <span class="divider">/</span></li> +<li <%= (el) -> el.data('step', 3) %>><span class='step'><%= pollen.poll.form.create.step3 %></span> <span class="divider">/</span></li> </ul> <form id='pollCreationForm' class="form-horizontal"> <!-- Basic info step --> <div class='step1'> + <h3><%= pollen.poll.form.create.step1 %></h3> + <div class="control-group"> <label class="control-label" for="pollCreationFormTitle"><%= pollen.poll.title.label %></label> <div class="controls"> - <input type='text' name='title' id='pollCreationFormTitle' + <input type='text' name='title' id='pollCreationFormTitle' class="input-xxlarge" placeholder='<%= pollen.poll.title.placeholder %>' value='<%= poll.attr("title")%>' <%= (el) -> el.data('owner', poll) %>/> @@ -23,7 +25,7 @@ <div class="control-group"> <label class="control-label" for='pollCreationFormDescription'><%= pollen.poll.description.label %></label> <div class="controls"> - <textarea id='pollCreationFormDescription' + <textarea id='pollCreationFormDescription' class="input-xxlarge" name='description' placeholder="<%= pollen.poll.description.placeholder %>" <%= (el) -> el.data('owner', poll) %>><%= poll.attr('description') %></textarea> @@ -33,7 +35,7 @@ <div class="control-group"> <label class="control-label" for='pollCreationFormCreatorName'><%= pollen.poll.creator.name.label %></label> <div class="controls"> - <input type='text' name='creator.name' id='pollCreationFormCreatorName' + <input type='text' name='creator.name' id='pollCreationFormCreatorName' class="input-xxlarge" placeholder='<%= pollen.poll.creator.name.placeholder %>' value='<%= poll.attr("creator.name")%>' <%= (el) -> el.data('owner', poll) %>/> @@ -43,7 +45,7 @@ <div class="control-group"> <label class="control-label" for='pollCreationFormCreatorEmail'><%= pollen.poll.creator.email.label %></label> <div class="controls"> - <input type='text' name='creator.email' id='pollCreationFormCreatorEmail' + <input type='text' name='creator.email' id='pollCreationFormCreatorEmail' class="input-xxlarge" placeholder='<%= pollen.poll.creator.email.placeholder %>' value='<%= poll.attr("creator.email")%>' <%= (el) -> el.data('owner', poll) %>/> @@ -51,41 +53,27 @@ </div> <div class="form-actions"> - <button type="button" class="btn btn-primary nextStep"><%= pollen.poll.form.create.button.next %></button> + <button type="button" class="btn nextStep"><%= pollen.poll.form.create.button.next %></button> </div> </div> <!-- choices step --> <div class='step2 hide'> - <div class="control-group"> - <label class="control-label" for="pollCreationFormVoteCountingType"><%= pollen.poll.voteCountingType.label %></label> - <div class="controls"> - <select name='voteCountingType' id='pollCreationFormVoteCountingType' <%= (el) -> el.data('owner', poll) %>> - <option value="1" <%= (el) -> el.data('description', 'normal') %>><%= pollen.choice.voteType.normal.label %></option> - <option value="2" <%= (el) -> el.data('description', 'percentage') %>><%= pollen.choice.voteType.percentage.label %></option> - <option value="3" <%= (el) -> el.data('description', 'condorcet') %>><%= pollen.choice.voteType.condorcet.label %></option> - <option value="4" <%= (el) -> el.data('description', 'number') %>><%= pollen.choice.voteType.number.label %></option> - <option value="5" <%= (el) -> el.data('description', 'borda') %>><%= pollen.choice.voteType.borda.label %></option> - <option value="6" <%= (el) -> el.data('description', 'alternative') %>><%= pollen.choice.voteType.alternative.label %></option> - <option value="7" <%= (el) -> el.data('description', 'coombs') %>><%= pollen.choice.voteType.coombs.label %></option> - </select> - <span id='pollCreationFormVoteCountingTypeHelp' class="help-block"><%= pollen.choice.voteType.normal.description %></span> - </div> - </div> + <h3><%= pollen.poll.form.create.step2 %></h3> - <% choices.each(function(choice) { %> - <div class="control-group controls-row"> + <% poll.choice.each(function(choice) { %> + <div class="control-group row-fluid"> <label class="control-label span1" for='pollCreationFormCreatorName'><%= pollen.poll.choice.name.label %></label> - <div class="controls span2"> - <input type='text' name='name' + <div class="controls span3"> + <input type='text' name='name' class="input-block-level" placeholder='<%= pollen.poll.choice.name.placeholder %>' value="<%= choice.attr('name') %>" <%= (el) -> el.data('owner', choice) %>/> </div> <label class="control-label span1" for='pollCreationFormCreatorName'><%= pollen.poll.choice.description.label %></label> - <div class="controls span3"> - <textarea name='description' class="" + <div class="controls span7"> + <textarea name='description' class="input-block-level" placeholder="<%= pollen.poll.choice.description.placeholder %>" <%= (el) -> el.data('owner', choice) %>><%= choice.attr('description') %></textarea> </div> @@ -93,8 +81,10 @@ <% }) %> <div class="form-actions"> + <button type="button" class="btn prevStep"><%= pollen.poll.form.create.button.previous %></button> <button type='button' class='btn addChoice'><%= pollen.poll.form.create.button.addChoice %></button> - <button type="button" class="btn btn-primary nextStep"><%= pollen.poll.form.create.button.next %></button> + <button type='submit' class="btn btn-primary"><%= pollen.poll.form.create.button.save %></button> + <button type="button" class="btn nextStep"><%= pollen.poll.form.create.button.next %></button> </div> </div> @@ -102,6 +92,8 @@ <!-- Options step --> <div class='step3 hide'> + <h3><%= pollen.poll.form.create.step3 %></h3> + <!-- dates --> <fieldset> <legend><%= pollen.poll.form.create.legend.validityDates %></legend> @@ -186,10 +178,11 @@ <div class="control-group"> <label class="control-label" for='pollCreationFormMaxChoiceNumber'><%= pollen.poll.maxChoiceNumber.label %></label> <div class="controls"> - <input type='number' name='maxChoiceNumber' id='pollCreationFormMaxChoiceNumber' + <input type='number' name='maxChoiceNumber' id='pollCreationFormMaxChoiceNumber' class="input-mini" placeholder='<%= pollen.poll.maxChoiceNumber.placeholder %>' value='<%= poll.attr("maxChoiceNumber")%>' <%= (el) -> el.data('owner', poll) %>/> + <span class="help-inline"><%= pollen.poll.maxChoiceNumber.help %></span> </div> </div> @@ -244,6 +237,42 @@ </div> </div> + <% + if (poll.attr("pollType") == "RESTRICTED") { + poll.voterList[0].each(function(voter) { + %> + <div class="control-group row-fluid"> + <label class="control-label span1"><%= pollen.poll.voter.name.label %></label> + <div class="controls span3"> + <input type='text' name='name' class="input-block-level" + placeholder='<%= pollen.poll.voter.name.placeholder %>' + value="<%= voter.attr('name') %>" + <%= (el) -> el.data('owner', voter) %>/> + </div> + + <label class="control-label span1"><%= pollen.poll.voter.email.label %></label> + <div class="controls span4"> + <input type='text' name='email' class="input-block-level" + placeholder='<%= pollen.poll.voter.email.placeholder %>' + value="<%= voter.attr('email') %>" + <%= (el) -> el.data('owner', voter) %>/> + </div> + + <label class="control-label span1"><%= pollen.poll.voter.weight.label %></label> + <div class="controls span1"> + <input type='text' name='weight' class="input-block-level" + placeholder='<%= pollen.poll.voter.weight.placeholder %>' + value="<%= voter.attr('weight') %>" + <%= (el) -> el.data('owner', voter) %>/> + </div> + + <button type="button" class='btn btn-danger span1'><i class="icon-minus icon-white"></i></button> + </div> + <% }) %> + <button type="button" class='btn btn-success span1'><i class="icon-plus icon-white"></i></button> + <% } %> + + </fieldset> <!-- results --> @@ -251,34 +280,22 @@ <legend><%= pollen.poll.form.create.legend.results %></legend> <div class="control-group"> - <label class="control-label" for="pollCreationFormResultVisibility"><%= pollen.poll.resultVisibility.label %></label> + <label class="control-label" for="pollCreationFormVoteCountingType"><%= pollen.poll.voteCountingType.label %></label> <div class="controls"> - <select name='resultVisibility' id='pollCreationFormResultVisibility' <%= (el) -> el.data('owner', poll) %>> - <option value="EVERYBODY"><%= pollen.poll.resultVisibility.everybody.label %></option> - <option value="VOTER"><%= pollen.poll.resultVisibility.voter.label %></option> - <option value="CREATOR"><%= pollen.poll.resultVisibility.creator.label %></option> + <select name='voteCountingType' id='pollCreationFormVoteCountingType' <%= (el) -> el.data('owner', poll) %>> + <option value="1" <%= (el) -> el.data('description', 'normal') %>><%= pollen.choice.voteType.normal.label %></option> + <option value="2" <%= (el) -> el.data('description', 'percentage') %>><%= pollen.choice.voteType.percentage.label %></option> + <option value="3" <%= (el) -> el.data('description', 'condorcet') %>><%= pollen.choice.voteType.condorcet.label %></option> + <option value="4" <%= (el) -> el.data('description', 'number') %>><%= pollen.choice.voteType.number.label %></option> + <option value="5" <%= (el) -> el.data('description', 'borda') %>><%= pollen.choice.voteType.borda.label %></option> + <option value="6" <%= (el) -> el.data('description', 'alternative') %>><%= pollen.choice.voteType.alternative.label %></option> + <option value="7" <%= (el) -> el.data('description', 'coombs') %>><%= pollen.choice.voteType.coombs.label %></option> </select> + <span id='pollCreationFormVoteCountingTypeHelp' class="help-block"><%= pollen.choice.voteType.normal.description %></span> </div> </div> <div class="control-group"> - <div class="controls"> - <label class="checkbox"> - <input type="checkbox" id='pollCreationFormContinuousResults' name="continuousResults" - <%= poll.attr('continuousResults') ? "checked": "" %> - <%= (el) -> el.data('owner', poll) %>/> - <%= pollen.poll.continuousResults.label %> - </label> - </div> - </div> - - </fieldset> - - <!-- notifications --> - <fieldset> - <legend><%= pollen.poll.form.create.legend.notifications %></legend> - - <div class="control-group"> <label class="control-label" for="pollCreationFormResultVisibility"><%= pollen.poll.resultVisibility.label %></label> <div class="controls"> <select name='resultVisibility' id='pollCreationFormResultVisibility' <%= (el) -> el.data('owner', poll) %>> @@ -301,7 +318,10 @@ </div> </fieldset> + + <div class="form-actions"> + <button type="button" class="btn prevStep"><%= pollen.poll.form.create.button.previous %></button> <button type='submit' class="btn btn-primary"><%= pollen.poll.form.create.button.save %></button> </div> </div> Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2014-02-17 07:06:51 UTC (rev 3869) +++ trunk/pom.xml 2014-03-12 09:46:22 UTC (rev 3870) @@ -136,12 +136,13 @@ <module>pollen-services</module> <module>pollen-rest-api</module> <module>pollen-ui-js</module> + <module>pollen-ui-angular</module> </modules> <scm> - <connection>scm:svn:http://svn.chorem.org/svn/pollen/trunk</connection> + <connection>scm:svn:https://svn.chorem.org/pollen/trunk</connection> <developerConnection> - scm:svn:http://svn.chorem.org/svn/pollen/trunk + scm:svn:https://svn.chorem.org/pollen/trunk </developerConnection> <url>http://www.chorem.org/repositories/browse/pollen/trunk</url> </scm>
participants (1)
-
kmorin@users.chorem.org