#
# Document List Handlers
#
+# TODO: security check
class BasicLibraryHandler(AnonymousBaseHandler):
allowed_methods = ('GET',)
return {'documents' : document_list}
+#
+# This handler controlls the document collection
+#
class LibraryHandler(BaseHandler):
allowed_methods = ('GET', 'POST')
anonymous = BasicLibraryHandler
+
@hglibrary
def read(self, request, lib):
"""Return the list of documents."""
lock.release()
except LibraryException, e:
import traceback
- return response.InternalError().django_response(\
- {'exception': traceback.format_exc()} )
+ return response.InternalError().django_response({
+ "reason": traceback.format_exc()
+ })
except DocumentAlreadyExists:
# Document is already there
- return response.EntityConflict().django_response(\
- {"reason": "Document %s already exists." % docid})
+ return response.EntityConflict().django_response({
+ "reason": "already-exists",
+ "message": "Document already exists." % docid
+ })
#
# Document Handlers
allowed_methods = ('GET')
@hglibrary
- def read(self, request, docid, lib):
+ def read(self, request, docid, lib, stylesheet='partial'):
"""Read document as html text"""
try:
revision = request.GET.get('revision', 'latest')
'message': 'Provided revision refers, to document "%s", but provided "%s"' % (document.id, docid) })
return librarian.html.transform(document.data('xml'), is_file=False, \
- parse_dublincore=False, stylesheet="partial",\
+ parse_dublincore=False, stylesheet=stylesheet,\
options={
"with-paths": 'boolean(1)',
})
# we're done :)
return document.data('xml')
else:
- xdoc = parser.WLDocument.from_string(document.data('xml'))
+ xdoc = parser.WLDocument.from_string(document.data('xml'),\
+ parse_dublincore=False)
ptext = xdoc.part_as_text(part)
if ptext is None:
"provided": target_rev,
"latest": udoc.revision })
- if not request.user.has_perm('explorer.document.can_share'):
- # User is not permitted to make a merge, right away
- # So we instead create a pull request in the database
- try:
- prq, created = PullRequest.get_or_create(
- source_revision = str(udoc.revision),
- defaults = {
- 'comitter': request.user,
- 'document': docid,
- 'status': "N",
- 'comment': form.cleaned_data['message'] or '$AUTO$ Document shared.',
- }
- )
-
- return response.RequestAccepted().django_response(\
- ticket_status=prq.status, \
- ticket_uri=reverse("pullrequest_view", args=[prq.id]) )
- except IntegrityError, e:
- return response.InternalError().django_response()
-
if form.cleaned_data['type'] == 'update':
# update is always performed from the file branch
# to the user branch
success, changed = udoc.update(request.user.username)
- if form.cleaned_data['type'] == 'share':
- success, changed = udoc.share(form.cleaned_data['message'])
+ if form.cleaned_data['type'] == 'share':
+ if not request.user.has_perm('explorer.document.can_share'):
+ # User is not permitted to make a merge, right away
+ # So we instead create a pull request in the database
+ try:
+ prq, created = PullRequest.objects.get_or_create(
+ source_revision = str(udoc.revision),
+ defaults = {
+ 'comitter': request.user,
+ 'document': docid,
+ 'status': "N",
+ 'comment': form.cleaned_data['message'] or '$AUTO$ Document shared.',
+ }
+ )
+
+ return response.RequestAccepted().django_response(\
+ ticket_status=prq.status, \
+ ticket_uri=reverse("pullrequest_view", args=[prq.id]) )
+ except IntegrityError:
+ return response.EntityConflict().django_response({
+ 'reason': 'request-already-exist'
+ })
+ else:
+ success, changed = udoc.share(form.cleaned_data['message'])
if not success:
return response.EntityConflict().django_response({
from piston.handler import BaseHandler, AnonymousBaseHandler
+from api.utils import hglibrary
from explorer.models import PullRequest
+from api.response import *
class PullRequestListHandler(BaseHandler):
allowed_methods = ('GET',)
class PullRequestHandler(BaseHandler):
- allowed_methods = ('GET',)
+ allowed_methods = ('GET', 'PUT')
def read(self, request, prq_id):
- return PullRequest.objects.get(id=prq_id)
\ No newline at end of file
+ return PullRequest.objects.get(id=prq_id)
+
+ def update(self, request, prq_id):
+ """Change the status of request"""
+
+ if not request.user.has_perm('explorer.document.can_share'):
+ return AccessDenied().django_response("Insufficient priviliges")
+
+ prq = PullRequest.objects.get(id=prq_id)
+
+ if not prq:
+ return EntityNotFound().django_response()
+
+
+ action = request.PUT.get('action', None)
+
+ if action == 'accept' and prq.status == 'N':
+ return self.accept_merge(prq)
+ elif action == 'reject' and prq.status in ['N', 'R']:
+ return self.reject_merge(prq)
+ else:
+ return BadRequest().django_response()
+
+
+ @hglibrary
+ def accept_merge(self, prq, lib):
+ doc = lib.document( prq.document )
+ udoc = doc.take( prq.comitter.username )
+ success, changed = udoc.share(prq.comment)
+
+ if not success:
+ return EntityConflict().django_response()
+
+ doc = doc.latest()
+
+ prq.status = 'A'
+ prq.merged_revisions = unicode(doc.revision)
+ prq.save()
+
+ return SuccessAllOk().django_response({
+ 'status': prq.status
+ })
+
+
+ def reject_merge(self, prq, lib):
+ prq.status = 'R'
+ prq.save()
+
+ return SuccessAllOk().django_response({
+ 'status': prq.status
+ })
+
+
+
+
+
+
+
def read(self, request):
groups = toolbar.models.ButtonGroup.objects.all()
- return [ {'name': g.name, 'position': g.position,\
- 'buttons': g.button_set.all()} for g in groups ]
-
+ return [g.to_dict(with_buttons=True) for g in groups]
class ScriptletsHandler(BaseHandler):
allowed_methods = ('GET',)
# Pull requests
url(r"^pull-requests$", pullrequest_collection,
- {'emitter_format': 'json'} ),
+ {'emitter_format': 'json'}, name="pullrequest_list" ),
url(r"^pull-requests/(?P<prq_id>\d+)$", pullrequest_rsrc,
- {'emitter_format': 'json'}, name="pullrequest_view" ),
-
+ {'emitter_format': 'json'}, name="pullrequest_view" ),
+
# Documents
url(r'^documents$', library_resource,
{'emitter_format': 'json'}, name="document_list_view"),
@login_required
def print_html(request, **kwargs):
from api.resources import document_html_resource
+
+ kwargs['stylesheet'] = 'legacy'
output = document_html_resource.handler.read(request, **kwargs)
# =================
# = Pull requests =
# =================
-#def pull_requests(request):
-# return direct_to_template(request, 'manager/pull_request.html', extra_context = {
-# 'objects': models.PullRequest.objects.all()} )
+def pull_requests(request):
+ from explorer.models import PullRequest
+
+ objects = PullRequest.objects.order_by('status')
+
+ if not request.user.has_perm('explorer.book.can_share'):
+ objects = objects.filter(comitter=request.user)
+
+
+ return direct_to_template(request, 'manager/pull_request.html',
+ extra_context = {'objects': objects} )
def __unicode__(self):
return self.name
+ def to_dict(self, with_buttons=False):
+ d = {'name': self.name, 'position': self.position}
+
+ if with_buttons:
+ d['buttons'] = [ b.to_dict() for b in self.button_set.all() ]
+
+ return d
#class ButtonGroupManager(models.Manager):
#
if self.key_mod & 0x01: mods.append('Alt')
if self.key_mod & 0x02: mods.append('Ctrl')
if self.key_mod & 0x04: mods.append('Shift')
- mods.append('"'+self.key+'"')
- return '+'.join(mods)
+ mods.append(str(self.key))
+ return '[' + '+'.join(mods) + ']'
+
+ def to_dict(self):
+ return {
+ 'label': self.label,
+ 'tooltip': (self.tooltip or '') + self.hotkey_name(),
+ 'key': self.key,
+ 'key_mod': self.key_mod,
+ 'params': self.params,
+ 'scriptlet_id': self.scriptlet_id
+ }
def __unicode__(self):
return self.label
-from fabric.api import run, local, settings, abort, env, cd, require, abort
+from __future__ import with_statement
+from fabric.api import *
+
def staging():
'''Use staging server'''
return bool(self._library._hgrepo.changelog.children(self.hgrev()))
def merge_with(self, other, user, message):
+ message = self._library._sanitize_string(message)
lock = self._library.lock(True)
try:
self._library._checkout(self._changectx.node())
return (True, False)
- return self._revision.merge_with(sv._revision, user=user)
+ return self._revision.merge_with(sv._revision, user=user,
+ message="$AUTO$ Personal branch update.")
finally:
lock.release()
if not local.parentof(main):
success, changed = main.merge_with(local, user=user, message=message)
+ success = True
+ changed = False
+
# Case 3:
# main *
# |
if not local.parentof(main):
success, changed = local.merge_with(main, user=user, \
message='$AUTO$ Local branch update during share.')
+
+ success = True
+ changed = False
else:
print "case 4"
ADMINS = (
(u'Marek Stępniowski', 'marek@stepniowski.com'),
+ (u'Łukasz Rekucki', 'lrekucki@gmail.com'),
)
MANAGERS = ADMINS
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'pl'
-import locale
-locale.setlocale(locale.LC_ALL, '')
+#import locale
+#locale.setlocale(locale.LC_ALL, '')
SITE_ID = 1
'django.contrib.sites',
'django.contrib.admin',
'django.contrib.admindocs',
-
+
+ 'piston',
'explorer',
'toolbar',
'api',
--- /dev/null
+/* Style widoku HTML. Nie należy tu ustawiać position ani marginesów */
+.htmlview {
+ font-size: 16px;
+ font: Georgia, "Times New Roman", serif;
+ line-height: 1.5em;
+ padding: 3em;
+}
+
+.htmlview div {
+ max-width: 36em;
+}
+
+.htmlview #toc {
+ display: none;
+}
+
+.htmlview a {
+ color: blue;
+ text-decoration: none;
+}
+
+.htmlview h1 {
+ font-size: 3em;
+ margin: 1.5em 0;
+ text-align: center;
+ line-height: 1.5em;
+ font-weight: bold;
+}
+
+.htmlview h2 {
+ font-size: 2em;
+ margin: 1.5em 0 0;
+ font-weight: bold;
+ line-height: 1.5em;
+}
+
+.htmlview h3 {
+ font-size: 1.5em;
+ margin: 1.5em 0 0;
+ font-weight: normal;
+ line-height: 1.5em;
+}
+
+.htmlview h4 {
+ font-size: 1em;
+ margin: 1.5em 0 0;
+ line-height: 1.5em;
+}
+
+.htmlview p {
+ margin: 0;
+}
+
+/* ======================== */
+/* = Footnotes and themes = */
+/* ======================== */
+.htmlview .theme-begin {
+ border-left: 0.1em solid #DDDDDD;
+ color: #777;
+ padding: 0 0.5em;
+ width: 7.5em;
+ font-style: normal;
+ font-weight: normal;
+ font-size: 16px;
+ float: right;
+ margin-right: -9.5em;
+ clear: both;
+ left: 40em;
+ line-height: 1.5em;
+ text-align: left;
+}
+
+.htmlview .annotation {
+ font-style: normal;
+ font-weight: normal;
+ font-size: 12px;
+}
+
+.htmlview #footnotes .annotation {
+ display: block;
+ float: left;
+ width: 2.5em;
+ clear: both;
+}
+
+.htmlview #footnotes div {
+ margin: 1.5em 0 0 0;
+}
+
+.htmlview #footnotes p {
+ margin-left: 2.5em;
+ font-size: 0.875em;
+}
+
+.htmlview blockquote {
+ font-size: 0.875em;
+}
+
+/* ============= */
+/* = Numbering = */
+/* ============= */
+.htmlview p {
+ position: relative;
+}
+
+.htmlview .anchor {
+ position: absolute;
+ margin: 0em;
+ left: -3em;
+ color: #777;
+ font-size: 12px;
+ width: 2em;
+ text-align: center;
+ padding: 0.25em 0.5em;
+ line-height: 1.5em;
+}
+
+.htmlview .anchor:hover, .htmlview .anchor:active {
+ color: #FFF;
+ background-color: #CCC;
+}
+
+/* =================== */
+/* = Custom elements = */
+/* =================== */
+.htmlview span.author {
+ font-size: 0.5em;
+ display: block;
+ line-height: 1.5em;
+ margin-bottom: 0.25em;
+}
+
+.htmlview span.collection {
+ font-size: 0.375em;
+ display: block;
+ line-height: 1.5em;
+ margin-bottom: -0.25em;
+}
+
+.htmlview span.subtitle {
+ font-size: 0.5em;
+ display: block;
+ line-height: 1.5em;
+ margin-top: -0.25em;
+}
+
+.htmlview div.didaskalia {
+ font-style: italic;
+ margin: 0.5em 0 0 1.5em;
+}
+
+.htmlview div.kwestia {
+ margin: 0.5em 0 0;
+}
+
+.htmlview div.stanza {
+ margin: 1.5em 0 0;
+}
+
+.htmlview div.kwestia div.stanza {
+ margin: 0;
+}
+
+.htmlview p.paragraph {
+ text-align: justify;
+ margin: 1.5em 0 0;
+}
+
+.htmlview p.motto {
+ text-align: justify;
+ font-style: italic;
+ margin: 1.5em 0 0;
+}
+
+.htmlview p.motto_podpis {
+ font-size: 0.875em;
+ text-align: right;
+}
+
+.htmlview div.fragment {
+ border-bottom: 0.1em solid #999;
+ padding-bottom: 1.5em;
+}
+
+.htmlview div.note p, .htmlview div.dedication p,
+.htmlview div.note p.paragraph, .htmlview div.dedication p.paragraph {
+ text-align: right;
+ font-style: italic;
+}
+
+.htmlview hr.spacer {
+ height: 3em;
+ visibility: hidden;
+}
+
+.htmlview hr.spacer-line {
+ margin: 1.5em 0;
+ border: none;
+ border-bottom: 0.1em solid #000;
+}
+
+.htmlview p.spacer-asterisk {
+ padding: 0;
+ margin: 1.5em 0;
+ text-align: center;
+}
+
+.htmlview div.person-list ol {
+ list-style: none;
+ padding: 0 0 0 1.5em;
+}
+
+.htmlview p.place-and-time {
+ font-style: italic;
+}
+
+.htmlview em.math, .htmlview em.foreign-word,
+.htmlview em.book-title, .htmlview em.didaskalia {
+ font-style: italic;
+}
+
+.htmlview em.author-emphasis {
+ letter-spacing: 0.1em;
+}
+
+.htmlview em.person {
+ font-style: normal;
+ font-variant: small-caps;
+}
--- /dev/null
+table.request-report
+{
+ border: 2px groove black;
+ font-size: 12pt;
+
+ margin-top: 3em;
+ margin-bottom: 2em;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.request-report td, .request-report th {
+ vertical-align: top;
+ border-right: 1px solid black;
+ border-bottom: 1px solid black;
+
+ padding: 0.4em 1em;
+ margin: 0em;
+}
+
+.request-report th {
+ background-color: black;
+ color: white;
+}
+
+.request-report .status-N {
+ background-color: teal;
+}
+
+.request-report .status-R {
+ background-color: red;
+}
+
+.request-report .status-A {
+ background-color: gray;
+}
\ No newline at end of file
this.render_template = function render_template(str, data){
// Figure out if we're getting a template, or if we need to
- // load the template - and be sure to cache the result.
+ // load the template - and be sure to cache the result.
var fn = !/^[\d\s-_]/.test(str) ?
cache[str] = cache[str] ||
render_template(document.getElementById(str).innerHTML) :
// Generate a reusable function that will serve as a template
// generator (and which will be cached).
+
new Function("obj",
"var p=[],print=function(){p.push.apply(p,arguments);};" +
// Introduce the data as local variables using with(){}
"with(obj){p.push('" +
- // Convert the template into pure JavaScript
+ // Convert the template into pure JavaScript
str
.replace(/[\r\t\n]/g, " ")
.split("<%").join("\t")
}
},
- loadSucceeded: function(data) {
+ loadSucceeded: function(data)
+ {
+ // do some escaping
+ $.each(data, function() {
+ $.each(this.buttons, function() {
+ //do some lame escapes
+ this.tooltip = this.tooltip.replace(/"/g, """);
+ });
+ });
this.set('buttons', data);
}
});
this.set('state', 'loading');
// load the transformed data
- messageCenter.addMessage('info', 'Wczytuję HTML...');
+ // messageCenter.addMessage('info', 'Wczytuję HTML...');
$.ajax({
url: this.htmlURL,
}
this.set('data', data);
this.set('state', 'synced');
- messageCenter.addMessage('success', 'Wczytałem HTML :-)');
+ // messageCenter.addMessage('success', 'Wczytałem HTML :-)');
},
- loadingFailed: function() {
+ loadingFailed: function(response) {
if (this.get('state') != 'loading') {
alert('erroneous state:', this.get('state'));
}
- this.set('error', 'Nie udało się załadować panelu');
+
+ var json_response = null;
+ var message = "";
+
+ try {
+ json_response = $.evalJSON(response.responseText);
+
+ if(json_response.reason == 'xml-parse-error') {
+
+ message = json_response.message.replace(/(line\s+)(\d+)(\s+)/i,
+ "<a class='xml-editor-ref' href='#xml-$2-1'>$1$2$3</a>");
+
+ message = message.replace(/(line\s+)(\d+)(\,\s*column\s+)(\d+)/i,
+ "<a class='xml-editor-ref' href='#xml-$2-$4'>$1$2$3$4</a>");
+
+
+ }
+ else {
+ message = json_response.message || json_response.reason || "nieznany błąd.";
+ }
+ }
+ catch (e) {
+ message = response.statusText;
+ }
+
+ this.set('error', '<p>Nie udało się wczytać widoku HTML: </p>' + message);
+
this.set('state', 'error');
- messageCenter.addMessage('error', 'Nie udało mi się wczytać HTML. Spróbuj ponownie :-(');
+ // messageCenter.addMessage('error', 'Nie udało mi się wczytać HTML. Spróbuj ponownie :-(');
},
getXMLPart: function(elem, callback)
$.ajax({
url: this.dataURL,
- dataType: 'text; charset=utf-8',
+ dataType: 'text',
data: {
revision: this.get('revision'),
part: path
toolbarUrl = $('#api-toolbar-url').text();
doc = new Editor.DocumentModel();
- var editor = new EditorView('#body-wrap', doc);
- editor.freeze();
- var flashView = new FlashView('#flashview', messageCenter);
- var splitView = new SplitView('#splitview', doc);
+ EditorView = new EditorView('#body-wrap', doc);
+ EditorView.freeze();
leftPanelView = new PanelContainerView('#left-panel-container', doc);
rightPanelContainer = new PanelContainerView('#right-panel-container', doc);
+
+ var flashView = new FlashView('#flashview', messageCenter);
});
buttonPressed: function(event)
{
+ var self = this;
var target = event.target;
var groupIndex = parseInt($(target).attr('ui:groupindex'), 10);
console.log('Executing', scriptletId, 'with params', params);
try {
- scriptletCenter.scriptlets[scriptletId](this.parent, params);
+ self.parent.freeze('Wykonuję akcję...');
+ setTimeout(function() {
+ scriptletCenter.scriptlets[scriptletId](self.parent, params);
+ self.parent.unfreeze();
+ }, 10);
} catch(e) {
- console.log("Scriptlet", scriptletId, "failed.");
+ console.log("Scriptlet", scriptletId, "failed.", e);
}
},
/*global View render_template panels */
var EditorView = View.extend({
- _className: 'EditorView',
- element: null,
- model: null,
- template: null,
+ _className: 'EditorView',
+ element: null,
+ model: null,
+ template: null,
- init: function(element, model, template) {
- this._super(element, model, template);
+ init: function(element, model, template) {
+ this._super(element, model, template);
- this.quickSaveButton = $('#action-quick-save', this.element).bind('click.editorview', this.quickSave.bind(this));
- this.commitButton = $('#action-commit', this.element).bind('click.editorview', this.commit.bind(this));
- this.updateButton = $('#action-update', this.element).bind('click.editorview', this.update.bind(this));
- this.mergeButton = $('#action-merge', this.element).bind('click.editorview', this.merge.bind(this));
+ this.quickSaveButton = $('#action-quick-save', this.element).bind('click.editorview', this.quickSave.bind(this));
+ this.commitButton = $('#action-commit', this.element).bind('click.editorview', this.commit.bind(this));
+ this.updateButton = $('#action-update', this.element).bind('click.editorview', this.update.bind(this));
+ this.mergeButton = $('#action-merge', this.element).bind('click.editorview', this.merge.bind(this));
- this.model.addObserver(this, 'state', this.modelStateChanged.bind(this));
- this.modelStateChanged('state', this.model.get('state'));
-
- // Inicjalizacja okien jQuery Modal
- $('#commit-dialog', this.element).
- jqm({
- modal: true,
- onShow: this.loadRelatedIssues.bind(this)
- });
+ this.model.addObserver(this, 'state', this.modelStateChanged.bind(this));
+ this.modelStateChanged('state', this.model.get('state'));
+
+ this.splitView = new SplitView('#splitview', doc);
+
+ // Inicjalizacja okien jQuery Modal
+ $('#commit-dialog', this.element).
+ jqm({
+ modal: true,
+ onShow: this.loadRelatedIssues.bind(this)
+ });
- $('#commit-dialog-cancel-button', this.element).click(function() {
- $('#commit-dialog-error-empty-message').hide();
- $('#commit-dialog').jqmHide();
- });
+ $('#commit-dialog-cancel-button', this.element).click(function() {
+ $('#commit-dialog-error-empty-message').hide();
+ $('#commit-dialog').jqmHide();
+ });
- // $('#split-dialog').jqm({
- // modal: true,
- // onShow: $.fbind(self, self.loadSplitDialog)
- // }).
- // jqmAddClose('button.dialog-close-button');
+ // $('#split-dialog').jqm({
+ // modal: true,
+ // onShow: $.fbind(self, self.loadSplitDialog)
+ // }).
+ // jqmAddClose('button.dialog-close-button');
- this.model.load();
- },
+ this.model.load();
+ },
- quickSave: function(event) {
- this.model.saveDirtyContentModel();
- },
+ quickSave: function(event) {
+ this.model.saveDirtyContentModel();
+ },
- commit: function(event) {
- $('#commit-dialog', this.element).jqmShow({callback: this.doCommit.bind(this)});
- },
+ commit: function(event) {
+ $('#commit-dialog', this.element).jqmShow({
+ callback: this.doCommit.bind(this)
+ });
+ },
- doCommit: function(message) {
- this.model.saveDirtyContentModel(message);
- },
+ doCommit: function(message) {
+ this.model.saveDirtyContentModel(message);
+ },
- update: function(event) {
- this.model.update();
- },
+ update: function(event) {
+ this.model.update();
+ },
- merge: function(event) {
- $('#commit-dialog', this.element).jqmShow({callback: this.doMerge.bind(this)});
- },
+ merge: function(event) {
+ $('#commit-dialog', this.element).jqmShow({
+ callback: this.doMerge.bind(this)
+ });
+ },
- doMerge: function(message) {
- this.model.merge(message);
- },
+ doMerge: function(message) {
+ this.model.merge(message);
+ },
- loadRelatedIssues: function(hash) {
- var self = this;
- var c = $('#commit-dialog-related-issues');
+ loadRelatedIssues: function(hash) {
+ var self = this;
+ var c = $('#commit-dialog-related-issues');
- $('#commit-dialog-save-button').click(function(event, data)
- {
- if ($('#commit-dialog-message').val().match(/^\s*$/)) {
- $('#commit-dialog-error-empty-message').fadeIn();
- } else {
- $('#commit-dialog-error-empty-message').hide();
- $('#commit-dialog').jqmHide();
+ $('#commit-dialog-save-button').click(function(event, data)
+ {
+ if ($('#commit-dialog-message').val().match(/^\s*$/)) {
+ $('#commit-dialog-error-empty-message').fadeIn();
+ } else {
+ $('#commit-dialog-error-empty-message').hide();
+ $('#commit-dialog').jqmHide();
- var message = $('#commit-dialog-message').val();
- $('#commit-dialog-related-issues input:checked')
- .each(function() { message += ' refs #' + $(this).val(); });
- console.log("COMMIT APROVED", hash.t);
- hash.t.callback(message);
- }
- return false;
- });
+ var message = $('#commit-dialog-message').val();
+ $('#commit-dialog-related-issues input:checked')
+ .each(function() {
+ message += ' refs #' + $(this).val();
+ });
+ console.log("COMMIT APROVED", hash.t);
+ hash.t.callback(message);
+ }
+ return false;
+ });
- $("div.loading-box", c).show();
- $("div.fatal-error-box", c).hide();
- $("div.container-box", c).hide();
+ $("div.loading-box", c).show();
+ $("div.fatal-error-box", c).hide();
+ $("div.container-box", c).hide();
- $.getJSON(c.attr('ui:ajax-src') + '?callback=?',
- function(data, status)
- {
- var fmt = '';
- $(data).each( function() {
- fmt += '<label><input type="checkbox" checked="checked"';
- fmt += ' value="' + this.id + '" />' + this.subject +'</label>\n';
- });
- $("div.container-box", c).html(fmt);
- $("div.loading-box", c).hide();
- $("div.container-box", c).show();
- });
+ $.getJSON(c.attr('ui:ajax-src') + '?callback=?',
+ function(data, status)
+ {
+ var fmt = '';
+ $(data).each( function() {
+ fmt += '<label><input type="checkbox" checked="checked"';
+ fmt += ' value="' + this.id + '" />' + this.subject +'</label>\n';
+ });
+ $("div.container-box", c).html(fmt);
+ $("div.loading-box", c).hide();
+ $("div.container-box", c).show();
+ });
- hash.w.show();
- },
+ hash.w.show();
+ },
- modelStateChanged: function(property, value) {
- // Uaktualnia stan przycisków
- if (value == 'dirty') {
- this.quickSaveButton.attr('disabled', null);
- this.commitButton.attr('disabled', null);
- this.updateButton.attr('disabled', 'disabled');
- this.mergeButton.attr('disabled', 'disabled');
- } else if (value == 'synced') {
- this.quickSaveButton.attr('disabled', 'disabled');
- this.commitButton.attr('disabled', 'disabled');
- this.updateButton.attr('disabled', null);
- this.mergeButton.attr('disabled', null);
- } else if (value == 'empty') {
- this.quickSaveButton.attr('disabled', 'disabled');
- this.commitButton.attr('disabled', 'disabled');
- this.updateButton.attr('disabled', 'disabled');
- this.mergeButton.attr('disabled', 'disabled');
- }
- },
+ modelStateChanged: function(property, value) {
+ // Uaktualnia stan przycisków
+ if (value == 'dirty') {
+ this.quickSaveButton.attr('disabled', null);
+ this.commitButton.attr('disabled', null);
+ this.updateButton.attr('disabled', 'disabled');
+ this.mergeButton.attr('disabled', 'disabled');
+ } else if (value == 'synced') {
+ this.quickSaveButton.attr('disabled', 'disabled');
+ this.commitButton.attr('disabled', 'disabled');
+ this.updateButton.attr('disabled', null);
+ this.mergeButton.attr('disabled', null);
+ } else if (value == 'empty') {
+ this.quickSaveButton.attr('disabled', 'disabled');
+ this.commitButton.attr('disabled', 'disabled');
+ this.updateButton.attr('disabled', 'disabled');
+ this.mergeButton.attr('disabled', 'disabled');
+ }
+ },
- dispose: function() {
- $('#action-quick-save', this.element).unbind('click.editorview');
- $('#action-commit', this.element).unbind('click.editorview');
- $('#action-update', this.element).unbind('click.editorview');
- $('#action-merge', this.element).unbind('click.editorview');
+ dispose: function() {
+ $('#action-quick-save', this.element).unbind('click.editorview');
+ $('#action-commit', this.element).unbind('click.editorview');
+ $('#action-update', this.element).unbind('click.editorview');
+ $('#action-merge', this.element).unbind('click.editorview');
- this.model.removeObserver(this);
- this._super();
- }
+ this.model.removeObserver(this);
+ this._super();
+ }
});
this.$printLink.attr('href', base + "?revision=" + this.model.get('revision'));
},
- modelStateChanged: function(property, value) {
+ modelStateChanged: function(property, value)
+ {
+ var self = $(this);
+
if (value == 'synced' || value == 'dirty') {
this.unfreeze();
} else if (value == 'unsynced') {
this.freeze('Zapisywanie...');
} else if (value == 'error') {
this.freeze(this.model.get('error'));
+ $('.xml-editor-ref', this.overlay).click(
+ function(event) {
+ console.log("Sending scroll rq.", this);
+ try {
+ var href = $(this).attr('href').split('-');
+ var line = parseInt(href[1]);
+ var column = parseInt(href[2]);
+
+ $(document).trigger('xml-scroll-request', {line:line, column:column});
+ } catch(e) {
+ console.log(e);
+ }
+
+ return false;
+ });
}
},
this._super();
this.$printLink = $('.html-print-link', this.element);
+ var base = this.$printLink.attr('ui:baseref');
+ this.$printLink.attr('href', base + "?revision=" + this.model.get('revision'));
+
this.element.bind('click', this.itemClicked.bind(this));
},
init: function(element, model) {
this._super(element, model, null);
this.element.css('position', 'relative');
- this._resizingSubviews = false;
+ this._resizingSubviews = false;
this.views = $(">*", this.element[0]).css({
position: 'absolute', // positioned inside splitter container
this.leftView = $(this.views[0]);
this.rightView = $(this.views[1]);
+
this.splitbar = $(this.views[2] || '<div></div>')
.insertAfter(this.leftView)
.css({
-/*global View CodeMirror ButtonToolbarView render_template panels */
+/*global View CodeMirror ToolbarView render_template panels */
var XMLView = View.extend({
_className: 'XMLView',
element: null,
var self = this;
$('.xmlview-toolbar', this.element).bind('resize.xmlview', this.resized.bind(this));
-
-
+
+ // scroll to the given position (if availble)
+ this.scrollCallback = this.scrollOnRequest.bind(this);
+ $(document).bind('xml-scroll-request', this.scrollCallback);
+
this.parent.freeze('Ładowanie edytora...');
this.editor = new CodeMirror($('.xmlview', this.element).get(0), {
parserfile: 'parsexml.js',
parserConfig: {
useHTMLKludges: false
},
- textWrapping: false,
+ textWrapping: true,
tabMode: 'spaces',
indentUnit: 0,
onChange: this.editorDataChanged.bind(this),
},
dispose: function() {
+ $(document).unbind('xml-scroll-request', this.scrollCallback);
+
this.model.removeObserver(this);
$(this.editor.frame).remove();
this._super();
var ch = String.fromCharCode(code & 0xff).toLowerCase();
/* # console.log(ch.charCodeAt(0), '#', buttons); */
- var buttons = $('.buttontoolbarview-button[title='+ch+']', this.element);
+ var buttons = $('.buttontoolbarview-button[hotkey='+ch+']', this.element);
var mod = 0;
if(event.altKey) mod |= 0x01;
this.buttonToolbar.buttonPressed({
target: button
});
+ },
+
+ scrollOnRequest: function(event, data)
+ {
+ try {
+ var line = this.editor.nthLine(data.line);
+ this.editor.selectLines(line, (data.column-1));
+ } catch(e) {
+ console.log('Exception in scrollOnRequest:', e);
+ }
}
});
<div class="buttontoolbarview-group toolbar-buttons-container" ui:groupIndex="<%= i %>" style="display: none">
<% for (var j=0; j < buttons[i].buttons.length; j++) { %>
<% if (buttons[i].buttons[j].scriptlet_id) { %>
- <button type="button" class="buttontoolbarview-button"
- title="<%= buttons[i].buttons[j].key %>"
+ <button type="button" class="buttontoolbarview-button"
+ title="<%= buttons[i].buttons[j].tooltip %>"
+ hotkey="<%= buttons[i].buttons[j].key %>"
ui:hotkey_mod="<%= buttons[i].buttons[j].key_mod %>"
ui:groupindex="<%= i %>" ui:buttonindex="<%= j %>">
<%= buttons[i].buttons[j].label %>
<html>
<head>
<title>{{docid}}</title>
- <link rel="stylesheet" href="{{STATIC_URL}}css/html.css" type="text/css" charset="utf-8">
+ <link rel="stylesheet" href="{{STATIC_URL}}css/html_print.css" type="text/css" charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
+{% extends 'base.html' %}
+
+{% block extrahead %}
+<link rel="stylesheet" href="{{ STATIC_URL }}css/managment.css" type="text/css" />
+<script type="text/javascript">
+
+
+ $(function() {
+
+ function refreshRow(id) {
+ var row = $('#request-' +id);
+
+ $.ajax({
+ url: '{% url pullrequest_list %}/'+id,
+ dataType: 'json',
+ type: 'GET',
+ success: function(data) {
+ row.removeClass('status-N');
+ row.removeClass('status-R');
+ row.removeClass('status-A');
+ row.addClass('status-'+ data.status);
+
+ $('.column-doc', row).html(data.document);
+ $('.column-status', row).html(data.status);
+
+ alert('Merge accepted.');
+ }
+ });
+
+ }
+
+ $('.accept-button').click(function()
+ {
+ var id = parseInt($(this).attr('title'));
+
+
+ $.ajax({
+ url: '{% url pullrequest_list %}/'+id,
+ data: {action: 'accept'},
+ dataType: 'json',
+ type: 'PUT',
+ success: function(data) {
+ refreshRow(id);
+ }
+ });
+
+ });
+
+ });
+</script>
+{% endblock %}
+
+{% block maincontent %}
+<table class="request-report" cellspacing="0">
+ <tr>
+ <th>Utwór</th><th>Użytkownik</th><th>Komentarz</th><th>Stan</th>
+ <th>Akcje</th>
+ </tr>
{% if objects %}
{% for pullreq in objects %}
- <p>{{ pullreq }}</p>
+ <tr class="status-{{pullreq.status}}" id="request-{{pullreq.id}}">
+ <td class="column-doc">{{ pullreq.document }}</td>
+ <td class="column-user">{{ pullreq.comitter }}</td>
+ <td class="column-comment">{{ pullreq.comment }}</td>
+ <td class="column-status"> {{ pullreq.status }}</td>
+ <td><button type="button" class="accept-button" title="{{pullreq.id}}">Akceptuj</button></td>
+ </tr>
+
{% endfor %}
{% else %}
- <p>Brak żądań</p>
+ <tr><td colspan="*">Brak żądań</td></tr>
{% endif %}
+</table>
+
+{% endblock %}
# Explorer:
url(r'^$', 'explorer.views.file_list', name='file_list'),
url(r'^file/upload', 'explorer.views.file_upload', name='file_upload'),
+
+
+ url(r'^managment/pull-requests$', 'explorer.views.pull_requests'),
# url(r'^images/(?P<folder>[^/]+)/$', 'explorer.views.folder_images', name='folder_image'),
# url(r'^images/$', 'explorer.views.folder_images', {'folder': '.'}, name='folder_image_ajax'),
url(r'^admin/(.*)', admin.site.root),
# Prototypes
- url(r'^wysiwyg-proto/', include('wysiwyg.urls')),
+# url(r'^wysiwyg-proto/', include('wysiwyg.urls')),
# Our über-restful api
url(r'^api/', include('api.urls') ),