Commit 6b1d46f5 by Kálmán Viktor

Merge branch 'master' into feature-helptexts

parents 09eda579 9e28c78c
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Level'
db.create_table(u'acl_level', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=50)),
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
('codename', self.gf('django.db.models.fields.CharField')(max_length=100)),
('weight', self.gf('django.db.models.fields.IntegerField')(null=True)),
))
db.send_create_signal(u'acl', ['Level'])
# Adding unique constraint on 'Level', fields ['content_type', 'codename']
db.create_unique(u'acl_level', ['content_type_id', 'codename'])
# Adding model 'ObjectLevel'
db.create_table(u'acl_objectlevel', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['acl.Level'])),
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
('object_id', self.gf('django.db.models.fields.CharField')(max_length=255)),
))
db.send_create_signal(u'acl', ['ObjectLevel'])
# Adding unique constraint on 'ObjectLevel', fields ['content_type', 'object_id', 'level']
db.create_unique(u'acl_objectlevel', ['content_type_id', 'object_id', 'level_id'])
# Adding M2M table for field users on 'ObjectLevel'
m2m_table_name = db.shorten_name(u'acl_objectlevel_users')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('objectlevel', models.ForeignKey(orm[u'acl.objectlevel'], null=False)),
('user', models.ForeignKey(orm[u'auth.user'], null=False))
))
db.create_unique(m2m_table_name, ['objectlevel_id', 'user_id'])
# Adding M2M table for field groups on 'ObjectLevel'
m2m_table_name = db.shorten_name(u'acl_objectlevel_groups')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('objectlevel', models.ForeignKey(orm[u'acl.objectlevel'], null=False)),
('group', models.ForeignKey(orm[u'auth.group'], null=False))
))
db.create_unique(m2m_table_name, ['objectlevel_id', 'group_id'])
def backwards(self, orm):
# Removing unique constraint on 'ObjectLevel', fields ['content_type', 'object_id', 'level']
db.delete_unique(u'acl_objectlevel', ['content_type_id', 'object_id', 'level_id'])
# Removing unique constraint on 'Level', fields ['content_type', 'codename']
db.delete_unique(u'acl_level', ['content_type_id', 'codename'])
# Deleting model 'Level'
db.delete_table(u'acl_level')
# Deleting model 'ObjectLevel'
db.delete_table(u'acl_objectlevel')
# Removing M2M table for field users on 'ObjectLevel'
db.delete_table(db.shorten_name(u'acl_objectlevel_users'))
# Removing M2M table for field groups on 'ObjectLevel'
db.delete_table(db.shorten_name(u'acl_objectlevel_groups'))
models = {
u'acl.level': {
'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Level'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'weight': ('django.db.models.fields.IntegerField', [], {'null': 'True'})
},
u'acl.objectlevel': {
'Meta': {'unique_together': "(('content_type', 'object_id', 'level'),)", 'object_name': 'ObjectLevel'},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['acl.Level']"}),
'object_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.User']", 'symmetrical': 'False'})
},
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['acl']
\ No newline at end of file
......@@ -15,29 +15,4 @@
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.db.models import TextField, ForeignKey
from django.contrib.auth.models import User
from ..models import AclBase
class TestModel(AclBase):
normal_field = TextField()
ACL_LEVELS = (
('alfa', 'Alfa'),
('bravo', 'Bravo'),
('charlie', 'Charlie'),
)
class Test2Model(AclBase):
normal2_field = TextField()
owner = ForeignKey(User, null=True)
ACL_LEVELS = (
('one', 'One'),
('two', 'Two'),
('three', 'Three'),
('owner', 'owner'),
)
from .test_acl import TestModel, Test2Model # noqa
......@@ -17,9 +17,31 @@
from django.test import TestCase
from django.contrib.auth.models import User, Group, AnonymousUser
from django.db.models import TextField, ForeignKey
from ..models import ObjectLevel
from .models import TestModel, Test2Model
from ..models import ObjectLevel, AclBase
class TestModel(AclBase):
normal_field = TextField()
ACL_LEVELS = (
('alfa', 'Alfa'),
('bravo', 'Bravo'),
('charlie', 'Charlie'),
)
class Test2Model(AclBase):
normal2_field = TextField()
owner = ForeignKey(User, null=True)
ACL_LEVELS = (
('one', 'One'),
('two', 'Two'),
('three', 'Three'),
('owner', 'owner'),
)
class AclUserTest(TestCase):
......
......@@ -19,6 +19,7 @@
"jquery-simple-slider": "https://github.com/BME-IK/jquery-simple-slider.git",
"bootbox": "~4.3.0",
"intro.js": "0.9.0",
"favico.js": "~0.3.5"
"favico.js": "~0.3.5",
"datatables": "~1.10.4"
}
}
......@@ -50,20 +50,20 @@ def get_env_variable(var_name, default=None):
########## PATH CONFIGURATION
# Absolute filesystem path to the Django project directory:
DJANGO_ROOT = dirname(dirname(abspath(__file__)))
BASE_DIR = dirname(dirname(abspath(__file__)))
# Absolute filesystem path to the top-level project folder:
SITE_ROOT = dirname(DJANGO_ROOT)
SITE_ROOT = dirname(BASE_DIR)
# Site name:
SITE_NAME = basename(DJANGO_ROOT)
SITE_NAME = basename(BASE_DIR)
# Url to site: (e.g. http://localhost:8080/)
DJANGO_URL = get_env_variable('DJANGO_URL', '/')
# Add our project to our pythonpath, this way we don't need to type our project
# name in our dotted import paths:
path.append(DJANGO_ROOT)
path.append(BASE_DIR)
########## END PATH CONFIGURATION
......@@ -78,14 +78,9 @@ TEMPLATE_DEBUG = DEBUG
########## MANAGER CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins
ADMINS = (
('Root', 'root@localhost'),
)
EMAIL_SUBJECT_PREFIX = get_env_variable('DJANGO_SUBJECT_PREFIX', '[CIRCLE] ')
# See: https://docs.djangoproject.com/en/dev/ref/settings/#managers
MANAGERS = ADMINS
########## END MANAGER CONFIGURATION
......@@ -198,6 +193,7 @@ PIPELINE_JS = {
"jquery-knob/dist/jquery.knob.min.js",
"jquery-simple-slider/js/simple-slider.js",
"favico.js/favico.js",
"datatables/media/js/jquery.dataTables.js",
"dashboard/dashboard.js",
"dashboard/activity.js",
"dashboard/group-details.js",
......@@ -215,6 +211,7 @@ PIPELINE_JS = {
"js/host.js",
"js/network.js",
"js/switch-port.js",
"js/host-list.js",
"autocomplete_light/autocomplete.js",
"autocomplete_light/widget.js",
"autocomplete_light/addanother.js",
......@@ -283,12 +280,6 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'dashboard.context_processors.extract_settings',
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
TEMPLATE_DIRS = (
normpath(join(SITE_ROOT, '../../site-circle/templates')),
......@@ -337,7 +328,6 @@ DJANGO_APPS = (
)
THIRD_PARTY_APPS = (
'south',
'django_tables2',
'crispy_forms',
'djcelery',
......@@ -349,6 +339,11 @@ THIRD_PARTY_APPS = (
'pipeline',
)
import django
if django.get_version() < '1.7':
THIRD_PARTY_APPS += 'south',
# Apps specific for this project go here.
LOCAL_APPS = (
'common',
......@@ -533,8 +528,14 @@ LOCALE_PATHS = (join(SITE_ROOT, 'locale'), )
COMPANY_NAME = "BME IK 2014"
SOUTH_MIGRATION_MODULES = {
'taggit': 'taggit.south_migrations',
'vm': 'vm.south_migrations',
'firewall': 'firewall.south_migrations',
'acl': 'acl.south_migrations',
'dashboard': 'dashboard.south_migrations',
'storage': 'storage.south_migrations',
}
graphite_host = environ.get("GRAPHITE_HOST", None)
graphite_port = environ.get("GRAPHITE_PORT", None)
if graphite_host and graphite_port:
......
......@@ -43,7 +43,7 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': normpath(join(DJANGO_ROOT, 'default.db')),
# 'NAME': normpath(join(BASE_DIR, 'default.db')),
# 'USER': '',
# 'PASSWORD': '',
# 'HOST': '',
......
......@@ -370,6 +370,12 @@ class HumanSortField(CharField):
def get_monitored_value(self, instance):
return getattr(instance, self.monitor)
def deconstruct(self):
name, path, args, kwargs = super(HumanSortField, self).deconstruct()
if self.monitor is not None:
kwargs['monitor'] = self.monitor
return name, path, args, kwargs
@staticmethod
def _partition(s, pred):
"""Partition a deque of chars to a tuple of a
......
......@@ -41,6 +41,7 @@ from django.forms.widgets import TextInput, HiddenInput
from django.template import Context
from django.template.loader import render_to_string
from django.utils.html import escape, format_html
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from sizefield.widgets import FileSizeWidget
from django.core.urlresolvers import reverse_lazy
......@@ -95,10 +96,10 @@ class VmSaveForm(OperationForm):
if default:
self.fields['name'].initial = default
if clone:
self.fields.insert(2, "clone", forms.BooleanField(
self.fields["clone"] = forms.BooleanField(
required=False, label=_("Clone template permissions"),
help_text=_("Clone the access list of parent template. Useful "
"for updating a template.")))
"for updating a template."))
class VmCustomizeForm(forms.Form):
......@@ -749,9 +750,9 @@ class VmRenewForm(OperationForm):
default = kwargs.pop('default')
super(VmRenewForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'lease', forms.ModelChoiceField(
self.fields['lease'] = forms.ModelChoiceField(
queryset=choices, initial=default, required=False,
empty_label=None, label=_('Length')))
empty_label=None, label=_('Length'))
if len(choices) < 2:
self.fields['lease'].widget = HiddenInput()
self.fields['save'].widget = HiddenInput()
......@@ -771,9 +772,9 @@ class VmMigrateForm(forms.Form):
default = kwargs.pop('default')
super(VmMigrateForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'to_node', forms.ModelChoiceField(
self.fields['to_node'] = forms.ModelChoiceField(
queryset=choices, initial=default, required=False,
widget=forms.RadioSelect(), label=_("Node")))
widget=forms.RadioSelect(), label=_("Node"))
class VmStateChangeForm(OperationForm):
......@@ -834,9 +835,9 @@ class VmDiskResizeForm(OperationForm):
super(VmDiskResizeForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'disk', forms.ModelChoiceField(
self.fields['disk'] = forms.ModelChoiceField(
queryset=choices, initial=self.disk, required=True,
empty_label=None, label=_('Disk')))
empty_label=None, label=_('Disk'))
if self.disk:
self.fields['disk'].widget = HiddenInput()
self.fields['size'].initial += self.disk.size
......@@ -870,9 +871,9 @@ class VmDiskRemoveForm(OperationForm):
super(VmDiskRemoveForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'disk', forms.ModelChoiceField(
self.fields['disk'] = forms.ModelChoiceField(
queryset=choices, initial=self.disk, required=True,
empty_label=None, label=_('Disk')))
empty_label=None, label=_('Disk'))
if self.disk:
self.fields['disk'].widget = HiddenInput()
......@@ -915,9 +916,9 @@ class VmRemoveInterfaceForm(OperationForm):
super(VmRemoveInterfaceForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'interface', forms.ModelChoiceField(
self.fields['interface'] = forms.ModelChoiceField(
queryset=choices, initial=self.interface, required=True,
empty_label=None, label=_('Interface')))
empty_label=None, label=_('Interface'))
if self.interface:
self.fields['interface'].widget = HiddenInput()
......@@ -951,18 +952,45 @@ class VmAddInterfaceForm(OperationForm):
self.fields['vlan'] = field
class DeployChoiceField(forms.ModelChoiceField):
def __init__(self, *args, **kwargs):
self.instance = kwargs.pop("instance")
super(DeployChoiceField, self).__init__(*args, **kwargs)
def label_from_instance(self, obj):
traits = set(obj.traits.all())
req_traits = set(self.instance.req_traits.all())
# if the subset is empty the node satisfies the required traits
subset = req_traits - traits
label = "%s %s" % (
"&#xf071" if subset else "&#xf00c;", escape(obj.name),
)
if subset:
missing_traits = ", ".join(map(lambda x: escape(x.name), subset))
label += _(" (missing_traits: %s)") % missing_traits
return mark_safe(label)
class VmDeployForm(OperationForm):
def __init__(self, *args, **kwargs):
choices = kwargs.pop('choices', None)
instance = kwargs.pop("instance")
super(VmDeployForm, self).__init__(*args, **kwargs)
if choices is not None:
self.fields.insert(0, 'node', forms.ModelChoiceField(
self.fields['node'] = DeployChoiceField(
queryset=choices, required=False, label=_('Node'), help_text=_(
"Deploy virtual machine to this node "
"(blank allows scheduling automatically).")))
"(blank allows scheduling automatically)."),
widget=forms.Select(attrs={
'class': "font-awesome-font",
}), instance=instance
)
class VmPortRemoveForm(OperationForm):
......@@ -972,9 +1000,9 @@ class VmPortRemoveForm(OperationForm):
super(VmPortRemoveForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'rule', forms.ModelChoiceField(
self.fields['rule'] = forms.ModelChoiceField(
queryset=choices, initial=self.rule, required=True,
empty_label=None, label=_('Port')))
empty_label=None, label=_('Port'))
if self.rule:
self.fields['rule'].widget = HiddenInput()
......@@ -991,9 +1019,9 @@ class VmPortAddForm(OperationForm):
super(VmPortAddForm, self).__init__(*args, **kwargs)
self.fields.insert(0, 'host', forms.ModelChoiceField(
self.fields['host'] = forms.ModelChoiceField(
queryset=choices, initial=self.host, required=True,
empty_label=None, label=_('Host')))
empty_label=None, label=_('Host'))
if self.host:
self.fields['host'].widget = HiddenInput()
......@@ -1183,7 +1211,10 @@ class TraitForm(forms.ModelForm):
class MyProfileForm(forms.ModelForm):
preferred_language = forms.ChoiceField(LANGUAGES_WITH_CODE)
preferred_language = forms.ChoiceField(
LANGUAGES_WITH_CODE,
label=_("Preferred language"),
)
class Meta:
fields = ('preferred_language', 'email_notifications',
......
......@@ -54,7 +54,9 @@ from .validators import connect_command_template_validator
logger = getLogger(__name__)
pwgen = User.objects.make_random_password
def pwgen():
return User.objects.make_random_password()
class Favourite(Model):
......
......@@ -137,16 +137,16 @@ $(function() {
}
var vm_state = $("#vm-details-state");
if (vm_state.length) {
vm_state.data("status", data['status']);
$("#vm-details-state span").html(data['human_readable_status'].toUpperCase());
vm_state.data("status", data['status']); // jshint ignore:line
$("#vm-details-state span").html(data.human_readable_status.toUpperCase());
}
if(data['status'] == "RUNNING") {
if(data['connect_uri']) {
if(data['status'] == "RUNNING") { // jshint ignore:line
if(data.connect_uri) {
$("#dashboard-vm-details-connect-button").removeClass('disabled');
}
$("[data-target=#_console]").attr("data-toggle", "pill").attr("href", "#console").parent("li").removeClass("disabled");
} else {
if(data['connect_uri']) {
if(data.connect_uri) {
$("#dashboard-vm-details-connect-button").addClass('disabled');
}
$("[data-target=#_console]").attr("data-toggle", "_pill").attr("href", "#").parent("li").addClass("disabled");
......@@ -181,7 +181,7 @@ $(function() {
String.prototype.hashCode = function() {
var hash = 0, i, chr, len;
if (this.length == 0) return hash;
if (this.length === 0) return hash;
for (i = 0, len = this.length; i < len; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
......
......@@ -44,7 +44,7 @@ $(function () {
if(xhr.status === 403) {
addMessage(gettext("Only the owners can delete the selected object."), "warning");
} else {
addMessage(gettext("An error occurred. (") + xhr.status + ")", 'danger')
addMessage(gettext("An error occurred. (") + xhr.status + ")", 'danger');
}
}
});
......@@ -189,8 +189,8 @@ $(function () {
}
}
search_result.sort(compareVmByFav);
for(var i=0; i<5 && i<search_result.length; i++)
html += generateVmHTML(search_result[i].pk, search_result[i].name,
for(i=0; i<5 && i<search_result.length; i++)
html += generateVmHTML(search_result[i].pk, search_result[i].name,
search_result[i].owner ? search_result[i].owner : search_result[i].host, search_result[i].icon,
search_result[i].status, search_result[i].fav,
(search_result.length < 5));
......@@ -513,19 +513,19 @@ function addModalConfirmation(func, data) {
});
}
function clientInstalledAction(location) {
function clientInstalledAction(location) {
setCookie('downloaded_client', true, 365 * 24 * 60 * 60 * 1000, "/");
window.location.href = location;
$('#confirmation-modal').modal("hide");
}
function setCookie(name, value, seconds, path) {
if (seconds!=null) {
if (seconds !== null) {
var today = new Date();
var expire = new Date();
expire.setTime(today.getTime() + seconds);
document.cookie = name+"="+escape(value)+"; expires="+expire.toUTCString()+"; path="+path;
}
document.cookie = name+"="+escape(value)+"; expires="+expire.toUTCString()+"; path="+path;
}
/* no js compatibility */
......@@ -539,7 +539,7 @@ function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
// for AJAX calls
......@@ -581,7 +581,7 @@ $.ajaxSetup({
$(function() {
yourlabs.TextWidget.prototype.getValue = function(choice) {
return choice.children().html();
}
};
});
var tagsToReplace = {
......
......@@ -188,11 +188,15 @@ html {
display: none;
}
.vm-details-home-name {
#group-details-rename-form {
display: inline-block;
}
.vm-details-home-name, #group-details-rename-form .input-group {
max-width: 401px;
}
#node-details-rename-name, #group-details-rename-name {
#node-details-rename-name {
max-width: 160px;
}
......
$(function() {
/* rename */
$("#group-details-h1-name, .group-details-rename-button").click(function() {
$("#group-details-h1-name").hide();
$("#group-details-rename").css('display', 'inline');
$("#group-details-rename-name").focus();
$("#group-details-h1-name span").hide();
$("#group-details-rename-form").show().css('display', 'inline-block');
$("#group-details-rename-name").select();
});
/* rename ajax */
$('#group-details-rename-submit').click(function() {
if(!$("#group-details-rename-name")[0].checkValidity()) {
return true;
}
var name = $('#group-details-rename-name').val();
$.ajax({
method: 'POST',
url: location