+++ /dev/null
- -----
- i18n
- -----
- Olivier Lamy
- -----
- 2012-01-19
- -----
-
-~~ Licensed to the Apache Software Foundation (ASF) under one
-~~ or more contributor license agreements. See the NOTICE file
-~~ distributed with this work for additional information
-~~ regarding copyright ownership. The ASF licenses this file
-~~ to you 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.
-
-~~ NOTE: For help with the syntax of this file, see:
-~~ http://maven.apache.org/guides/mini/guide-apt-format.html
-
-i18n management
-
- The js library {{{http://code.google.com/p/jquery-i18n-properties}jquery-i18n-properties}} is used for i18n.
-
- On application loading, i18n properties are loaded by calling a REST services with the browser lang
- or with the requested language specified by the request parameter : ?request_lang=en.
-
- This service will load properties in this order:
-
- * redback properties in en then in specified language
-
- * archiva properties (from org/apache/archiva/i18n/default.properties) in en then in specified language
-
-* Javascript method
-
- Simple i18n value without any value
-
-+-----------------------
-Javascript code :
-$.i18n.prop("save") will return the value for key save
-+-----------------------
-
-
- You can pass some values too (sample for property managedrepository.deleted=Managed Repository " {0} " deleted. )
-
-+-----------------------
-Javascript code :
-$.i18n.prop("managedrepository.deleted",managedRepository.name())
-if managedRepository.name() is "foo"
-response will be Managed Repository " foo " deleted.
-+-----------------------
-
-* Missing properties
-
- In case of missing property, the key is returned.
\ No newline at end of file
+++ /dev/null
- -----
- Knockout binding
- -----
- Olivier Lamy
- -----
- 2012-01-19
- -----
-
-~~ Licensed to the Apache Software Foundation (ASF) under one
-~~ or more contributor license agreements. See the NOTICE file
-~~ distributed with this work for additional information
-~~ regarding copyright ownership. The ASF licenses this file
-~~ to you 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.
-
-~~ NOTE: For help with the syntax of this file, see:
-~~ http://maven.apache.org/guides/mini/guide-apt-format.html
-
-Knockout binding
-
- Explanation on the managed repositories list/edit/add screen.
-
-%{toc}
-
-* Javascript Beans
-
- First you must map the json response on a Javascript bean (a bit borying task :-) )
-
-+-------------------
-Java class with fields
-
-public class ManagedRepository
- //private String id;
-
- //private String name;
- ....
-
-Javascript
-ManagedRepository=function(id,name,.....){
-
- this.id=ko.observable(id);
-
- this.name=ko.observable(name);
-
-mapping function (to map the json result to your javascript beans)
-
- mapManagedRepositories=function(data){
- var mappedManagedRepositories = $.map(data.managedRepository, function(item) {
- return mapManagedRepository(item);
- });
- return mappedManagedRepositories;
- }
- mapManagedRepository=function(data){
- if (data==null){
- return null;
- }
- return new ManagedRepository(data.id,data.name,data.layout,data.indexDirectory,data.location,data.snapshots,data.releases,
- data.blockRedeployments,data.cronExpression,
- data.scanned,data.daysOlder,data.retentionCount,data.deleteReleasedSnapshots,data.stageRepoNeeded);
- }
-
-+-------------------
-
- <<<NOTE to have access to field values you must now managedRepository.name() >>>
-
-* View Model
-
-** First you must insert your template in the #main-content div
-
-+---------------
-// it's a jquery template as we do some i18n transformations
-$("#main-content").html($("#repositoriesMain").tmpl());
-+---------------
-
-** You can now create your view model.
-
-+---------------
-ManagedRepositoriesViewModel=function(){
- //field which will receive values
- this.managedRepositories=ko.observableArray([]);
- // method which will edit an entry: an other view model is created
- editManagedRepository=function(managedRepository){
- var viewModel = new ManagedRepositoryViewModel(managedRepository,true,self);
- ...
- ko.applyBindings(viewModel,$("#main-content #managed-repository-edit").get(0));
- ..
- }
- // method which will delete an entry
- removeManagedRepository=function(managedRepository){
- ......
- }
-}
-+---------------
-
-** Grid binding
-
- The ManagedRepositoriesViewModel is used as it with a custom grid binding (knockout has a feature to create own binding
- so we use one called <<<simpleGrid>>> which will display grids.
-
- Grid view initialisation code (some details omitted) :
-
-+----------------
- var managedRepositoriesViewModel = new ManagedRepositoriesViewModel();
-
- $.ajax("restServices/archivaServices/managedRepositoriesService/getManagedRepositories", {
- type: "GET",
- dataType: 'json',
- success: function(data) {
- // data mapping json -> javascript
- managedRepositoriesViewModel.managedRepositories(mapManagedRepositories(data));
- // we define here our grid view model for fields only displayed
- managedRepositoriesViewModel.gridViewModel = new ko.simpleGrid.viewModel({
- data: managedRepositoriesViewModel.managedRepositories,
- columns: [
- {
- headerText: $.i18n.prop('identifier'),
- rowText: "id"
- },
- {
- headerText: $.i18n.prop('name'),
- rowText: "name"
- },
- {
- headerText: $.i18n.prop('type'),
- rowText: "getTypeLabel",
- // FIXME i18n
- title: "Repository type (default is Maven 2)"
- }
- ],
- // max items per size, the binding has a pagination feature
- pageSize: 5,
- // we can define here a callback function which be called on all grid change (adding/updating/removing values from the array)
- gridUpdateCallBack: function(){
- $("#main-content #managed-repositories-table [title]").tooltip();
- }
- });
- // apply the binding on the specified node
- ko.applyBindings(managedRepositoriesViewModel,$("#main-content #managed-repositories-table").get(0));
- }
- }
- );
-+----------------
-
-* View definition
-
-** Binding definition
-
- We have applyed binding on the node with id "#managed-repositories-table". The binding definition is:
-
-+----------------
- <table class="bordered-table zebra-striped" id="managed-repositories-table"
- data-bind="simpleGrid: gridViewModel,simpleGridTemplate:'ko_managed-repositoriesGrid',pageLinksId:'managed-repositoriesPagination',data:'managedRepositories'">
- </table>
-+----------------
-
- * simpleGrid: gridViewModel = field name for the view model (see sample above)
-
- * simpleGridTemplate:'ko_managed-repositoriesGrid' = name of the template to use (see below)
-
- * pageLinksId:'managed-repositoriesPagination' = name of the template to use for pagination.
-
- * data:'managedRepositories' = fields which contains data to pass to pass to the template
-
-** Template content
-
- Template used for grid display (some details omitted).
-
-+----------------
-<script id='ko_managed-repositoriesGrid' type='text/x-jquery-tmpl'>
- <thead>
- <tr>
- // display read only fields defined in ko.simpleGrid.viewModel.columns (see above)
- {{each(i, columnDefinition) columns}}
- <th title="${ columnDefinition.title }">${ columnDefinition.headerText }</th>
- {{/each}}
- <th>Releases</th>
- .....
- // custom columns
- <th>${$.i18n.prop('edit')}</th>
- <th>${$.i18n.prop('delete')}</th>
- </tr>
- </thead>
- <tbody>
- {{each(i, row) itemsOnCurrentPage()}}
- <tr>
- // display read only fields defined in ko.simpleGrid.viewModel.columns (see above)
- {{each(j, columnDefinition) columns}}
- <td>${ typeof columnDefinition.rowText == 'function' ? columnDefinition.rowText(row) : row[columnDefinition.rowText] }</td>
- {{/each}}
- // custom columns which images depending on a value
- <td>
- {{if row.releases() == true}}
- <img src="images/weather-clear.png" title="${$.i18n.prop('release.included')}"/>
- {{else}}
- <img src="images/dialog-error.png" title="${$.i18n.prop('release.notincluded')}"/>
- {{/if}}
- </td>
- .....
- // custom columns with binding mapped to ManagedRepositoriesViewModel methods
- <td><a href="#" data-bind="click: function(){ editManagedRepository(row) }">${$.i18n.prop('edit')}</a></td>
- <td>
- <a href="#" data-bind="click: function(){ removeManagedRepository(row) }">
- <img src="images/edit-cut.png" title="${$.i18n.prop('delete')}"/>
- </a>
- </td>
- .....
- </tr>
- {{/each}}
- </tbody>
-
-+----------------
+++ /dev/null
- -----
- REST Services
- -----
- Olivier Lamy
- -----
- 2012-01-19
- -----
-
-~~ Licensed to the Apache Software Foundation (ASF) under one
-~~ or more contributor license agreements. See the NOTICE file
-~~ distributed with this work for additional information
-~~ regarding copyright ownership. The ASF licenses this file
-~~ to you 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.
-
-~~ NOTE: For help with the syntax of this file, see:
-~~ http://maven.apache.org/guides/mini/guide-apt-format.html
-
-Expose Rest Services
-
-
- The {{{http://cxf.apache.org}Apache CXF}} is used to expose some classes/methods as REST Services.
-
- Services use the standard interface/implementation pattern:
-
- * interfaces and beans are located in archiva-rest-api maven module
-
- * implementation are located in archiva-rest-services maven module
-
- []
-
-%{toc}
-
-* Steps to expose your class as a REST Service.
-
- Here all the steps to expose a new class as a REST service.
-
-** Interface and data beans
-
- All interfaces and data beans are added in the module archiva-rest-api:
-
- * interface in the package: org.apache.archiva.rest.api.services .
-
- * data beans in the package: org.apache.archiva.rest.api.model .
-
- []
-
-*** Beans
-
- As we want to be able to expose result as json or xml type, all beans use javax.xml.bind.annotation root element :
-
-+---------------------
-@XmlRootElement( name = "artifact" )
-public class Artifact
- implements Serializable
-
-All services will be able to return json or xml
-@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
-+---------------------
-
-*** JAXRS annotations
-
- As we use interfaces/implementations pattern jaxrs annotations are only in interfaces level.
-
-+---------------------
-@Path( "/managedRepositoriesService/" )
-public interface ManagedRepositoriesService
-{
- // simple GET method no parameter
- @Path( "getManagedRepositories" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- List<ManagedRepository> getManagedRepositories()
- throws ArchivaRestServiceException;
-
- // GET method with a path parameter
- @Path( "getManagedRepository/{repositoryId}" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- ManagedRepository getManagedRepository( @PathParam( "repositoryId" ) String repositoryId )
- throws ArchivaRestServiceException;
-
- // POST method to pass a data bean
- @Path( "addManagedRepository" )
- @POST
- @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- ManagedRepository addManagedRepository( ManagedRepository managedRepository )
- throws ArchivaRestServiceException;
-+---------------------
-
-** CXF/Spring configuration
-
- REST services implementations are marked with the Spring annotation @Service
-
-+---------------------
-package org.apache.archiva.rest.services;
-......
-@Service( "managedRepositoriesService#rest" )
-public class DefaultManagedRepositoriesService
- extends AbstractRestService
- implements ManagedRepositoriesService
-+---------------------
-
- Spring beans are declared as REST/CXF services in the Spring configuration
-
-+---------------------
- <jaxrs:server id="archivaServices" address="/archivaServices">
- .....
- <jaxrs:serviceBeans>
- <ref bean="managedRepositoriesService#rest"/>
- </jaxrs:serviceBeans>
- .....
- </jaxrs:server>
-
- Note as we use @Service annotation package scanning must declared in spring configuration
-
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd ....">
-...
- <context:annotation-config/>
- <context:component-scan
- base-package="org.apache.archiva.rest.services"/>
-
-...
-</beans>
-+---------------------
-
- CXF servlet is declared as:
-
-+---------------------
- <servlet>
- <servlet-name>CXFServlet</servlet-name>
- <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>CXFServlet</servlet-name>
- <url-pattern>/restServices/*</url-pattern>
- </servlet-mapping>
-+---------------------
-
- So as it, REST services are availble in the following url <<restServices/archivaServices/>>.
-
-** Redback security annotation
-
- Some REST methods need some karma, so to prevent anonymous access methods can be marked as it:
-
-+---------------------
-
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION )
- ManagedRepository addManagedRepository( ManagedRepository managedRepository )
- throws ArchivaRestServiceException;
-+---------------------
-
- This method will need the current user to have the operation manage-configuration level.
-
- For more details, have a look at {{{http://redback.codehaus.org/integration/rest.html}Redback REST}}.
-
-
-
-
-
-
-
+++ /dev/null
- -----
- Javascript template loading
- -----
- Olivier Lamy
- -----
- 2012-01-19
- -----
-
-~~ Licensed to the Apache Software Foundation (ASF) under one
-~~ or more contributor license agreements. See the NOTICE file
-~~ distributed with this work for additional information
-~~ regarding copyright ownership. The ASF licenses this file
-~~ to you 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.
-
-~~ NOTE: For help with the syntax of this file, see:
-~~ http://maven.apache.org/guides/mini/guide-apt-format.html
-
-Html/Javascript templates loading
-
- Templates are loaded on application loaded and added in the hidden div <<#html-fragments>>.
-
- They are loaded using requirejs and the text plugin.
-
- archiva templates are loaded as it <<<NOTE: the no cache is activated only on dev mode>>>
-
-+-------------------------
-require(["text!archiva/templates/menu.html?"+timestampNoCache(),"text!archiva/templates/topbar.html?"+timestampNoCache(),
- "text!archiva/templates/message.html?"+timestampNoCache(),"text!archiva/templates/modal.html?"+timestampNoCache(),
- "text!archiva/templates/grids-generics.html?"+timestampNoCache(),
- "text!archiva/templates/repositories.html?"+timestampNoCache()],
- function(menu,topbar,message,modal,grids_generics,repositories) {
-
- // template loading
- $.tmpl( menu ).appendTo("#html-fragments");
- $.tmpl( topbar ).appendTo("#html-fragments");
- $("#html-fragments").append(message);
- $.tmpl( modal ).appendTo("#html-fragments");
- $("#html-fragments").append(grids_generics);
- $("#html-fragments").append(repositories);
- $.log("main-tmpl.js menu loaded");
- }
-);
-+-------------------------
-
-* i18n in templates
-
-** static templates
-
- Some templates which are only simple html which only need i18n are executed immediatly.
-
- Simply use:
-
-+-------------------------
- $.tmpl( menu, $.i18n.map ).appendTo("#html-fragments");
- to get i18n values in your template you can use
- ${register} or ${$.i18n.prop('register')}
-
- Note if you use the simple form ${register} and the property is not available, the template system will try to use if exists the function register
-
-+-------------------------
-
-
-** dynamic templates
-
- The others are only inserted in #html-fragments.
\ No newline at end of file
+++ /dev/null
-$(document).ready(function(){
- $("a.single_image").fancybox({
- 'transitionIn' : 'elastic',
- 'transitionOut' : 'elastic',
- 'speedIn' : 600,
- 'speedOut' : 200,
- 'overlayShow' : true
- });
- $("a.gallery_image").fancybox({
- 'transitionIn' : 'elastic',
- 'transitionOut' : 'elastic',
- 'speedIn' : 600,
- 'speedOut' : 200,
- 'overlayShow' : true,
- 'titlePosition': 'inside'
- });
-});
-
+++ /dev/null
-<?xml version="1.0"?>
-
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<document>
- <properties>
- <title>Generics Javascript</title>
- <author>Olivier Lamy</author>
- </properties>
- <body>
-
- <script src="js/jquery-1.7.js" type="text/javascript"></script>
- <script src="js/jquery.fancybox.pack-2.0.4.js" type="text/javascript"></script>
- <script src="js/jquery.mousewheel-3.0.6.pack.js" type="text/javascript"></script>
- <link rel="stylesheet" href="css/jquery.fancybox-2.0.4.css" type="text/css" media="screen" />
- <script type="text/javascript" src="js/fancy-box-activation.js"></script>
-
- <macro name="toc"/>
-
- <section name="Generics Javascript">
- <p>Some common/generic javascript methods are available.</p>
- <subsection name="User messages">
- <p>A div "user-messages" is reserved for user messages.</p>
- <subsection name="Success message">
- <p>
- Javascript function:
- <source>
-displaySuccessMessage($.i18n.prop('managedrepository.added'));
-// the second parameter is optionnal by default user-messages id is used
-displaySuccessMessage=function(text,idToAppend){
- </source>
- <a href="images/success-message.png" class="single_image" title="Success Message">
- <img src="images/success-message.png" width="150" height="93" style="border: 1px solid silver; margin-left: 0.25em; margin-bottom: 0.25em" alt="" /><br/>
- Success Message
- </a>
- </p>
- </subsection>
-
- <subsection name="Error message">
- <p>
- Javascript function:
- <source>
-displayErrorMessage($.i18n.prop('managedrepository.added'));
-// the second parameter is optionnal by default user-messages id is used
-displayErrorMessage=function(text,idToAppend){
- </source>
- <a href="images/error-message.png" class="single_image" title="Error Message">
- <img src="images/error-message.png" width="150" height="93" style="border: 1px solid silver; margin-left: 0.25em; margin-bottom: 0.25em" alt="" /><br/>
- Error Message
- </a>
- </p>
- </subsection>
- </subsection>
- <subsection name="Modal Confirm dialog">
- <p>
- Javascript function:
- <source>
-okFn: function to call in case of ok
-okMessage: message for Ok button
-cancelMessage: message for cancel button
-title: modal title
-bodyText: modal content (can be html)
-openDialogConfirm=function(okFn, okMessage, cancelMessage, title,bodyText)
- </source>
- <a href="images/modal-confirm-dialog.png" class="single_image" title="Modal Confirm dialog">
- <img src="images/modal-confirm-dialog.png" width="150" height="93" style="border: 1px solid silver; margin-left: 0.25em; margin-bottom: 0.25em" alt="" /><br/>
- Modal Confirm dialog
- </a>
- </p>
- </subsection>
- </section>
- </body>
-</document>
-
-
+++ /dev/null
-<?xml version="1.0"?>
-
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<document>
- <properties>
- <title>Archiva Javascript application General design</title>
- <author>Olivier Lamy</author>
- </properties>
- <body>
-
- <script src="js/jquery-1.7.js" type="text/javascript"></script>
- <script src="js/jquery.fancybox.pack-2.0.4.js" type="text/javascript"></script>
- <script src="js/jquery.mousewheel-3.0.6.pack.js" type="text/javascript"></script>
- <link rel="stylesheet" href="css/jquery.fancybox-2.0.4.css" type="text/css" media="screen" />
- <script type="text/javascript" src="js/fancy-box-activation.js"></script>
-
-
- <macro name="toc"/>
-
- <section name="Archiva Javascript Web Application">
- <subsection name="General design">
- <p>
- The goal is to have a "one page loading" javascript application.
- <br/>
- For this the only html page will contains a div with id "main-content" this div will be populated
- by jquery template execution (see <a href="./template-loading.html">template loading</a>).
- <br/>
- The server will be contacted only for REST request/response (see <a href="./rest.html">details</a>).
- <br/>
- <b>All UI rendering will be done only on client side.</b>
- <br/>
- As we are not designer :-), the application will use the <a href="http://twitter.github.com/bootstrap" target="_blank">twitter bootstrap css</a>.
- </p>
- </subsection>
- <subsection name="Runtime Properties">
- <p>The application is designed to use http cache mechanism for css, javascript. Except REST call to get datas which will never use cache as a query timestamp parameter is used.
- But as this can cause issue in developpement phase, two system properties (disabled by default) prevent can prevent caching and/or help debuging
- <ul>
- <li>archiva.devMode=true/false: if true will add a timestamp query parameter for loading js and html templates.</li>
- <li>archiva.javascriptLog=true/false: will activate javascript log, method available with $.log(msg)</li>
- <li>archiva.logMissingI18n=true/false: will activate remote logging of missing i18n key in the servlet container log: INFO archivaMissingi18n.logger - missing i18n key : 'proxy-connectors.grid.managedrepo.title'</li>
- </ul>
- </p>
- </subsection>
- <subsection name="Used Javascript frameworks">
- <p>
- We use some well known javascript framework librairies :
- <ul>
- <li><a target="_blank" href="http://jquery.com/">jquery</a>.</li>
-
- <li><a target="_blank" href="http://labjs.com">labjs</a> for javascript loading.</li>
-
- <li><a target="_blank" href="http://requirejs.org">requirejs</a> for template loading (see <a href="./template-loading.html">details</a>.</li>
-
- <li><a target="_blank" href="http://code.google.com/p/jquery-i18n-properties">jquery-i18n-properties</a> for i18n loading (see <a href="./i18n.html">details</a>.</li>
-
- <li><a target="_blank" href="http://knockoutjs.com">knockoutjs</a> as we use a MVVM pattern (see <a href="./knockout-binding.html">knockout binding</a>).</li>
-
- <li><a target="_blank" href="http://twitter.github.com/bootstrap/javascript.html">twitter bootstrap js</a> to magnify the ui.</li>
-
- <li><a target="_blank" href="http://bassistance.de/jquery-plugins/jquery-plugin-validation">jquery validate</a> for form validation.</li>
- </ul>
- </p>
- </subsection>
- <subsection name="Sources organisation">
- <p>
- Sources are located in <a target="_blank" href="http://svn.apache.org/repos/asf/archiva/trunk/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/">src/main/webapp</a> :
- <ul>
- <li>css</li>
- <li>images</li>
- <li>js</li>
- </ul>
- </p>
- <subsection name="js directory">
- <p>
- Root directory contains external libraries.
- </p>
- <p>
- archiva directory contains archiva js files with a subdirectory templates which contains templates
- </p>
- <p>
- redback directory contains redback js files with a subdirectory templates which contains templates
- </p>
- </subsection>
- </subsection>
-
- <subsection name="Start page">
- <p>
- The main page will load javascript files, load <a href="./i18n.html">i18n</a>, <a href="./template-loading.html">load templates</a> and insert menu.
- <br/>
- This main page is divided in 3 parts:
- <p>
- <a href="images/start-screen.png" class="single_image" title="Start Page">
- <img src="images/start-screen.png" width="150" height="93" style="border: 1px solid silver; margin-left: 0.25em; margin-bottom: 0.25em" alt="" /><br/>
- Start Page
- </a>
- </p>
- <p>
- <ul>
- <li>#topbar-menu-container is populated with the template js/archiva/templates/topbar.html.</li>
- <li>#sidebar-content is populated with the template js/archiva/templates/menu.html.</li>
- <li>#main-content is the place where screen will appear.</li>
- <li>hidden #html-fragments will contains loaded templates.</li>
- </ul>
- </p>
- <p>
- Link are visible/hide depending on needed redback karmas.
- You can configure redback operations needed for a link using the attribute redback-permissions in your html element
- (by default element needed karma must be marked display: none):
- <source>
-<![CDATA[
-Support array: at least one operation is needed:
-<div .... redback-permissions="{permissions: ['archiva-manage-users','archiva-manage-configuration']}" style="display: none">
-Support single value:
-<li style="display: none" redback-permissions="{permissions: ['archiva-manage-users']}">
-]]>
- </source>
-
- </p>
- </p>
- </subsection>
-
- <subsection name="Grid/edit model">
- <p>We use a tab/pill models to display grid of datas and edit/add form:
- <ul>
- <li>
- One tab/pill display the grid
- <a href="images/repo-grids.png" class="single_image" title="Repositories Grid">
- <img src="images/repo-grids.png" width="150" height="93" style="border: 1px solid silver; margin-left: 0.25em; margin-bottom: 0.25em" alt="" /><br/>
- Repositories Grid
- </a>
- </li>
- <li>
- One tab/pill display the edit/add form. <b>As we use knockout framework grid will be updated with new value from add/edit form automatically.</b>
- <a href="images/repo-edit.png" class="single_image" title="Repositories Edit/Add">
- <img src="images/repo-edit.png" width="150" height="93" style="border: 1px solid silver; margin-left: 0.25em; margin-bottom: 0.25em" alt="" /><br/>
- Repositories Edit/Add
- </a>
- </li>
- </ul>
- Have a look at the page <a href="./knockout-binding.html">knockout-binding</a> for more explanation.
- </p>
- </subsection>
-
- </section>
- </body>
-</document>
-
-