Unverified Commit f9578f44 authored by BaiJiangJie's avatar BaiJiangJie Committed by GitHub

Merge pull request #3606 from jumpserver/dev

Dev
parents a27fb18a a37e1422
...@@ -5,10 +5,9 @@ ...@@ -5,10 +5,9 @@
{% block table_search %}{% endblock %} {% block table_search %}{% endblock %}
{% block table_container %} {% block table_container %}
<div class="btn-group uc pull-left m-r-5"> <div class="btn-group uc pull-left m-r-5">
<button class="btn btn-sm btn-primary"> <button data-toggle="dropdown" class="btn btn-primary btn-sm dropdown-toggle">
{% trans "Create DatabaseApp" %} {% trans "Create DatabaseApp" %}
</button> <span class="caret"></span></button>
<button data-toggle="dropdown" class="btn btn-primary btn-sm dropdown-toggle"><span class="caret"></span></button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
{% for key, value in type_choices %} {% for key, value in type_choices %}
<li><a class="" href="{% url 'applications:database-app-create' %}?type={{ key }}">{{ value }}</a></li> <li><a class="" href="{% url 'applications:database-app-create' %}?type={{ key }}">{{ value }}</a></li>
......
...@@ -7,10 +7,9 @@ ...@@ -7,10 +7,9 @@
{% block table_search %}{% endblock %} {% block table_search %}{% endblock %}
{% block table_container %} {% block table_container %}
<div class="btn-group uc pull-left m-r-5"> <div class="btn-group uc pull-left m-r-5">
<button class="btn btn-sm btn-primary"> <button data-toggle="dropdown" class="btn btn-primary btn-sm dropdown-toggle">
{% trans "Create RemoteApp" %} {% trans "Create RemoteApp" %}
</button> <span class="caret"></span></button>
<button data-toggle="dropdown" class="btn btn-primary btn-sm dropdown-toggle"><span class="caret"></span></button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
{% for key, value in type_choices %} {% for key, value in type_choices %}
<li><a class="" href="{% url 'applications:remote-app-create' %}?type={{ key }}">{{ value }}</a></li> <li><a class="" href="{% url 'applications:remote-app-create' %}?type={{ key }}">{{ value }}</a></li>
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from django.utils.translation import ugettext_lazy as _
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT = _(
'Cannot contain special characters: [ {} ]'
).format(" ".join(['/', '\\']))
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN = r"[/\\]"
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG = \
_("* The contains characters that are not allowed")
...@@ -7,7 +7,6 @@ from common.utils import get_logger ...@@ -7,7 +7,6 @@ from common.utils import get_logger
from orgs.mixins.forms import OrgModelForm from orgs.mixins.forms import OrgModelForm
from ..models import Asset from ..models import Asset
from ..const import GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT
logger = get_logger(__file__) logger = get_logger(__file__)
...@@ -82,7 +81,6 @@ class AssetCreateUpdateForm(OrgModelForm): ...@@ -82,7 +81,6 @@ class AssetCreateUpdateForm(OrgModelForm):
'nodes': _("Node"), 'nodes': _("Node"),
} }
help_texts = { help_texts = {
'hostname': GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT,
'admin_user': _( 'admin_user': _(
'root or other NOPASSWD sudo privilege user existed in asset,' 'root or other NOPASSWD sudo privilege user existed in asset,'
'If asset is windows or other set any one, more see admin user left menu' 'If asset is windows or other set any one, more see admin user left menu'
......
...@@ -6,7 +6,6 @@ from django.utils.translation import gettext_lazy as _ ...@@ -6,7 +6,6 @@ from django.utils.translation import gettext_lazy as _
from common.utils import validate_ssh_private_key, ssh_pubkey_gen, get_logger from common.utils import validate_ssh_private_key, ssh_pubkey_gen, get_logger
from orgs.mixins.forms import OrgModelForm from orgs.mixins.forms import OrgModelForm
from ..models import AdminUser, SystemUser from ..models import AdminUser, SystemUser
from ..const import GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT
logger = get_logger(__file__) logger = get_logger(__file__)
__all__ = [ __all__ = [
...@@ -99,7 +98,6 @@ class SystemUserForm(OrgModelForm, PasswordAndKeyAuthForm): ...@@ -99,7 +98,6 @@ class SystemUserForm(OrgModelForm, PasswordAndKeyAuthForm):
}), }),
} }
help_texts = { help_texts = {
'name': GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT,
'auto_push': _('Auto push system user to asset'), 'auto_push': _('Auto push system user to asset'),
'priority': _('1-100, High level will be using login asset as default, ' 'priority': _('1-100, High level will be using login asset as default, '
'if user was granted more than 2 system user'), 'if user was granted more than 2 system user'),
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import io
import os import os
import uuid import uuid
from hashlib import md5 from hashlib import md5
...@@ -76,6 +77,14 @@ class AssetUser(OrgModelMixin): ...@@ -76,6 +77,14 @@ class AssetUser(OrgModelMixin):
i = '-'.join(str(self.id).split('-')[:3]) i = '-'.join(str(self.id).split('-')[:3])
return i return i
def get_private_key(self):
if not self.private_key_obj:
return None
string_io = io.StringIO()
self.private_key_obj.write_private_key(string_io)
private_key = string_io.getvalue()
return private_key
def get_related_assets(self): def get_related_assets(self):
assets = self.assets.all() assets = self.assets.all()
return assets return assets
......
...@@ -8,10 +8,6 @@ from django.utils.translation import ugettext_lazy as _ ...@@ -8,10 +8,6 @@ from django.utils.translation import ugettext_lazy as _
from orgs.mixins.serializers import BulkOrgResourceModelSerializer from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from common.serializers import AdaptedBulkListSerializer from common.serializers import AdaptedBulkListSerializer
from ..models import Asset, Node, Label, Platform from ..models import Asset, Node, Label, Platform
from ..const import (
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN,
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
)
from .base import ConnectivitySerializer from .base import ConnectivitySerializer
__all__ = [ __all__ = [
...@@ -100,15 +96,6 @@ class AssetSerializer(BulkOrgResourceModelSerializer): ...@@ -100,15 +96,6 @@ class AssetSerializer(BulkOrgResourceModelSerializer):
'org_name': {'label': _('Org name')} 'org_name': {'label': _('Org name')}
} }
@staticmethod
def validate_hostname(hostname):
pattern = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN
res = re.search(pattern, hostname)
if res is not None:
msg = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
raise serializers.ValidationError(msg)
return hostname
@classmethod @classmethod
def setup_eager_loading(cls, queryset): def setup_eager_loading(cls, queryset):
""" Perform necessary eager loading of data. """ """ Perform necessary eager loading of data. """
......
...@@ -9,10 +9,6 @@ from common.utils import ssh_pubkey_gen ...@@ -9,10 +9,6 @@ from common.utils import ssh_pubkey_gen
from orgs.mixins.serializers import BulkOrgResourceModelSerializer from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from assets.models import Node from assets.models import Node
from ..models import SystemUser from ..models import SystemUser
from ..const import (
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN,
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
)
from .base import AuthSerializer, AuthSerializerMixin from .base import AuthSerializer, AuthSerializerMixin
__all__ = [ __all__ = [
...@@ -47,15 +43,6 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): ...@@ -47,15 +43,6 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
'created_by': {'read_only': True}, 'created_by': {'read_only': True},
} }
@staticmethod
def validate_name(name):
pattern = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN
res = re.search(pattern, name)
if res is not None:
msg = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
raise serializers.ValidationError(msg)
return name
def validate_auto_push(self, value): def validate_auto_push(self, value):
login_mode = self.initial_data.get("login_mode") login_mode = self.initial_data.get("login_mode")
protocol = self.initial_data.get("protocol") protocol = self.initial_data.get("protocol")
...@@ -136,6 +123,7 @@ class SystemUserAuthSerializer(AuthSerializer): ...@@ -136,6 +123,7 @@ class SystemUserAuthSerializer(AuthSerializer):
""" """
系统用户认证信息 系统用户认证信息
""" """
private_key = serializers.SerializerMethodField()
class Meta: class Meta:
model = SystemUser model = SystemUser
...@@ -144,6 +132,10 @@ class SystemUserAuthSerializer(AuthSerializer): ...@@ -144,6 +132,10 @@ class SystemUserAuthSerializer(AuthSerializer):
"login_mode", "password", "private_key", "login_mode", "password", "private_key",
] ]
@staticmethod
def get_private_key(obj):
return obj.get_private_key()
class SystemUserSimpleSerializer(serializers.ModelSerializer): class SystemUserSimpleSerializer(serializers.ModelSerializer):
""" """
......
This diff is collapsed.
...@@ -119,12 +119,6 @@ ...@@ -119,12 +119,6 @@
check: { check: {
enable: true enable: true
}, },
async: {
enable: true,
url: url,
autoParam: ["id=key", "name=n", "level=lv"],
type: 'get'
},
view: { view: {
dblClickExpand: false, dblClickExpand: false,
showLine: true showLine: true
......
...@@ -4,10 +4,6 @@ from rest_framework.serializers import ModelSerializer ...@@ -4,10 +4,6 @@ from rest_framework.serializers import ModelSerializer
from rest_framework import serializers from rest_framework import serializers
from users.models import User, UserGroup from users.models import User, UserGroup
from assets.models import Asset, Domain, AdminUser, SystemUser, Label from assets.models import Asset, Domain, AdminUser, SystemUser, Label
from assets.const import (
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN,
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
)
from perms.models import AssetPermission from perms.models import AssetPermission
from common.serializers import AdaptedBulkListSerializer from common.serializers import AdaptedBulkListSerializer
from .utils import set_current_org, get_current_org from .utils import set_current_org, get_current_org
...@@ -22,15 +18,6 @@ class OrgSerializer(ModelSerializer): ...@@ -22,15 +18,6 @@ class OrgSerializer(ModelSerializer):
fields = '__all__' fields = '__all__'
read_only_fields = ['created_by', 'date_created'] read_only_fields = ['created_by', 'date_created']
@staticmethod
def validate_name(name):
pattern = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN
res = re.search(pattern, name)
if res is not None:
msg = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
raise serializers.ValidationError(msg)
return name
class OrgReadSerializer(ModelSerializer): class OrgReadSerializer(ModelSerializer):
admins = serializers.SlugRelatedField(slug_field='name', many=True, read_only=True) admins = serializers.SlugRelatedField(slug_field='name', many=True, read_only=True)
......
...@@ -1237,7 +1237,7 @@ function toSafeDateISOStr(s) { ...@@ -1237,7 +1237,7 @@ function toSafeDateISOStr(s) {
function toSafeLocalDateStr(d) { function toSafeLocalDateStr(d) {
var date = safeDate(d); var date = safeDate(d);
var date_s = date.toLocaleString(navigator.language, {hour12: false}); var date_s = date.toLocaleString(getUserLang(), {hour12: false});
return date_s.split("/").join('-') return date_s.split("/").join('-')
} }
...@@ -1257,7 +1257,7 @@ function getTimeUnits(u) { ...@@ -1257,7 +1257,7 @@ function getTimeUnits(u) {
"m": "分", "m": "分",
"s": "秒", "s": "秒",
}; };
if (navigator.language === "zh-CN") { if (getUserLang() === "zh-CN") {
return units[u] return units[u]
} }
return u return u
...@@ -1395,6 +1395,16 @@ function showCeleryTaskLog(taskId) { ...@@ -1395,6 +1395,16 @@ function showCeleryTaskLog(taskId) {
window.open(url, '', 'width=900,height=600') window.open(url, '', 'width=900,height=600')
} }
function getUserLang(){
let userLangZh = document.cookie.indexOf('django_language=zh');
if (userLangZh !== -1){
return 'zh-CN'
}
else{
return 'en-US'
}
}
function initDateRangePicker(selector, options) { function initDateRangePicker(selector, options) {
if (!options) { if (!options) {
options = {} options = {}
...@@ -1408,6 +1418,15 @@ function initDateRangePicker(selector, options) { ...@@ -1408,6 +1418,15 @@ function initDateRangePicker(selector, options) {
daysOfWeek: ["日", "一", "二", "三", "四", "五", "六"],//汉化处理 daysOfWeek: ["日", "一", "二", "三", "四", "五", "六"],//汉化处理
monthNames: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], monthNames: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
}; };
var enLocale = {
format: "YYYY-MM-DD HH:mm",
separator: " - ",
applyLabel: "Apply",
cancelLabel: "Cancel",
resetLabel: "Reset",
daysOfWeek: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
monthNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
};
var defaultOption = { var defaultOption = {
singleDatePicker: true, singleDatePicker: true,
showDropdowns: true, showDropdowns: true,
...@@ -1415,10 +1434,13 @@ function initDateRangePicker(selector, options) { ...@@ -1415,10 +1434,13 @@ function initDateRangePicker(selector, options) {
timePicker24Hour: true, timePicker24Hour: true,
autoApply: true, autoApply: true,
}; };
var userLang = navigator.language || navigator.userLanguage; if (getUserLang() === 'zh-CN') {
if (userLang.indexOf('zh') !== -1) {
defaultOption.locale = zhLocale; defaultOption.locale = zhLocale;
} }
else{
// en-US
defaultOption.locale = enLocale;
}
options = Object.assign(defaultOption, options); options = Object.assign(defaultOption, options);
return $(selector).daterangepicker(options); return $(selector).daterangepicker(options);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<script src="{% static "js/plugins/toastr/toastr.min.js" %}"></script> <script src="{% static "js/plugins/toastr/toastr.min.js" %}"></script>
<script src="{% static "js/inspinia.js" %}"></script> <script src="{% static "js/inspinia.js" %}"></script>
<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script> <script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script src="{% static "js/jumpserver.js" %}?v=6"></script> <script src="{% static "js/jumpserver.js" %}?v=7"></script>
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script> <script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
<script src="{% static 'js/plugins/select2/i18n/zh-CN.js' %}"></script> <script src="{% static 'js/plugins/select2/i18n/zh-CN.js' %}"></script>
<script> <script>
...@@ -18,9 +18,6 @@ $(document).ready(function(){ ...@@ -18,9 +18,6 @@ $(document).ready(function(){
if ($('.tooltip')[0]) { if ($('.tooltip')[0]) {
$('.tooltip').tooltip(); $('.tooltip').tooltip();
} }
var userLang = navigator.language || navigator.userLanguage; $.fn.select2.defaults.set('language', getUserLang())
if (userLang.indexOf('zh') !== -1) {
$.fn.select2.defaults.set('language', 'zh-CN')
}
}); });
</script> </script>
...@@ -54,13 +54,15 @@ ...@@ -54,13 +54,15 @@
{# Applications #} {# Applications #}
{% if request.user.can_admin_current_org and LICENSE_VALID %} {% if request.user.can_admin_current_org %}
<li id="applications"> <li id="applications">
<a> <a>
<i class="fa fa-th" style="width: 14px"></i> <span class="nav-label">{% trans 'Applications' %}</span><span class="fa arrow"></span> <i class="fa fa-th" style="width: 14px"></i> <span class="nav-label">{% trans 'Applications' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
{% if LICENSE_VALID %}
<li id="remote-app"><a href="{% url 'applications:remote-app-list' %}">{% trans 'RemoteApp' %}</a></li> <li id="remote-app"><a href="{% url 'applications:remote-app-list' %}">{% trans 'RemoteApp' %}</a></li>
{% endif %}
<li id="database-app"><a href="{% url 'applications:database-app-list' %}">{% trans 'DatabaseApp' %}</a></li> <li id="database-app"><a href="{% url 'applications:database-app-list' %}">{% trans 'DatabaseApp' %}</a></li>
</ul> </ul>
</li> </li>
...@@ -79,10 +81,10 @@ ...@@ -79,10 +81,10 @@
<li id="remote-app-permission"> <li id="remote-app-permission">
<a href="{% url 'perms:remote-app-permission-list' %}">{% trans 'RemoteApp' %}</a> <a href="{% url 'perms:remote-app-permission-list' %}">{% trans 'RemoteApp' %}</a>
</li> </li>
{% endif %}
<li id="database-app-permission"> <li id="database-app-permission">
<a href="{% url 'perms:database-app-permission-list' %}">{% trans 'DatabaseApp' %}</a> <a href="{% url 'perms:database-app-permission-list' %}">{% trans 'DatabaseApp' %}</a>
</li> </li>
{% endif %}
</ul> </ul>
</li> </li>
{% endif %} {% endif %}
......
...@@ -5,17 +5,18 @@ ...@@ -5,17 +5,18 @@
</a> </a>
</li> </li>
{% if LICENSE_VALID %}
<li id="applications"> <li id="applications">
<a> <a>
<i class="fa fa-th" style="width: 14px"></i> <span class="nav-label">{% trans 'My Applications' %}</span><span class="fa arrow"></span> <i class="fa fa-th" style="width: 14px"></i> <span class="nav-label">{% trans 'My Applications' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
{% if LICENSE_VALID %}
<li id="user-remote-app"> <li id="user-remote-app">
<a href="{% url 'applications:user-remote-app-list' %}"> <a href="{% url 'applications:user-remote-app-list' %}">
<i class="" style="width: 14px"></i><span class="nav-label">{% trans 'RemoteApp' %}</span><span class="label label-info pull-right"></span> <i class="" style="width: 14px"></i><span class="nav-label">{% trans 'RemoteApp' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
{% endif %}
<li id="user-database-app"> <li id="user-database-app">
<a href="{% url 'applications:user-database-app-list' %}"> <a href="{% url 'applications:user-database-app-list' %}">
<i class="" style="width: 14px"></i><span class="nav-label">{% trans 'DatabaseApp' %}</span><span class="label label-info pull-right"></span> <i class="" style="width: 14px"></i><span class="nav-label">{% trans 'DatabaseApp' %}</span><span class="label label-info pull-right"></span>
...@@ -23,7 +24,6 @@ ...@@ -23,7 +24,6 @@
</li> </li>
</ul> </ul>
</li> </li>
{% endif %}
{% if SECURITY_COMMAND_EXECUTION %} {% if SECURITY_COMMAND_EXECUTION %}
<li id="ops"> <li id="ops">
......
...@@ -41,7 +41,7 @@ class Migration(migrations.Migration): ...@@ -41,7 +41,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='session', model_name='session',
name='asset', name='asset',
field=models.CharField(db_index=True, max_length=1024, field=models.CharField(db_index=True, max_length=128,
verbose_name='Asset'), verbose_name='Asset'),
), ),
migrations.AlterField( migrations.AlterField(
......
...@@ -175,7 +175,7 @@ class Session(OrgModelMixin): ...@@ -175,7 +175,7 @@ class Session(OrgModelMixin):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
user = models.CharField(max_length=128, verbose_name=_("User"), db_index=True) user = models.CharField(max_length=128, verbose_name=_("User"), db_index=True)
user_id = models.CharField(blank=True, default='', max_length=36, db_index=True) user_id = models.CharField(blank=True, default='', max_length=36, db_index=True)
asset = models.CharField(max_length=1024, verbose_name=_("Asset"), db_index=True) asset = models.CharField(max_length=128, verbose_name=_("Asset"), db_index=True)
asset_id = models.CharField(blank=True, default='', max_length=36, db_index=True) asset_id = models.CharField(blank=True, default='', max_length=36, db_index=True)
system_user = models.CharField(max_length=128, verbose_name=_("System user"), db_index=True) system_user = models.CharField(max_length=128, verbose_name=_("System user"), db_index=True)
system_user_id = models.CharField(blank=True, default='', max_length=36, db_index=True) system_user_id = models.CharField(blank=True, default='', max_length=36, db_index=True)
......
...@@ -13,10 +13,9 @@ ...@@ -13,10 +13,9 @@
<div id="my-tickets" class="tab-pane active"> <div id="my-tickets" class="tab-pane active">
<div class="panel-body"> <div class="panel-body">
<div class="btn-group uc pull-left m-r-5"> <div class="btn-group uc pull-left m-r-5">
<button class="btn btn-sm btn-primary"> <button data-toggle="dropdown" class="btn btn-primary btn-sm dropdown-toggle">
{% block create_storage_info %}{% endblock %} {% block create_storage_info %}{% endblock %}
</button> <span class="caret"></span></button>
<button data-toggle="dropdown" class="btn btn-primary btn-sm dropdown-toggle"><span class="caret"></span></button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
{% for key, value in type_choices %} {% for key, value in type_choices %}
<li><a class="" href="{% block create_storage_url %}{% endblock %}?type={{ key }}">{{ value }}</a></li> <li><a class="" href="{% block create_storage_url %}{% endblock %}?type={{ key }}">{{ value }}</a></li>
......
...@@ -86,7 +86,7 @@ $(document).ready(function () { ...@@ -86,7 +86,7 @@ $(document).ready(function () {
forceParse: false, forceParse: false,
calendarWeeks: true, calendarWeeks: true,
autoclose: true, autoclose: true,
language: navigator.language || "en", language: getUserLang(),
}; };
dateFromRef.datepicker(options).on("changeDate", function () { dateFromRef.datepicker(options).on("changeDate", function () {
var value = $(this).val() + ' 0:0:0'; var value = $(this).val() + ' 0:0:0';
......
...@@ -193,7 +193,7 @@ $(document).ready(function() { ...@@ -193,7 +193,7 @@ $(document).ready(function() {
forceParse: false, forceParse: false,
calendarWeeks: true, calendarWeeks: true,
autoclose: true, autoclose: true,
language: navigator.language || "en", language: getUserLang(),
}; };
dateFromRef.datepicker(options).on("changeDate", function () { dateFromRef.datepicker(options).on("changeDate", function () {
if (!$(this).val()) { if (!$(this).val()) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment