Commit d65b84ee by aa.gusti

perbaikan datatable dan css

1 parent a3d64342
body { body {
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
--font-weight: 300; --font-weight: 300;
--color: #ffffff; --color: #ffffff;
--background: #bc2131; --background: #bc2131;
font-size: 12px !important; font-size: 12px !important;
padding-top: 40px; padding-top: 40px;
} }
h1, h1,
h2, h2,
h3, h3,
...@@ -21,107 +21,116 @@ legend { ...@@ -21,107 +21,116 @@ legend {
} }
.bar { .bar {
height: 18px; height: 18px;
background: green; background: green;
} }
.twitter-typeahead .tt-query, .twitter-typeahead .tt-query,
.twitter-typeahead .tt-hint { .twitter-typeahead .tt-hint {
margin-bottom: 0; margin-bottom: 0;
width: 100%; width: 100%;
height: 26px; height: 26px;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
} }
.twitter-typeahead .tt-hint { .twitter-typeahead .tt-hint {
color: #a1a1a1; color: #a1a1a1;
z-index: 1; z-index: 1;
padding: 3px 6px; padding: 3px 6px;
border: 1px solid transparent; border: 1px solid transparent;
} }
.select2-container .select2-selection--single .select2-selection__rendered {
/* display: block; */
/* padding-left: 8px; */
/* padding-right: 20px; */
overflow: hidden;
/* text-overflow: ellipsis; */
/* white-space: nowrap; */
padding: 3px 6px;
}
.form-control { .form-control {
font-size: 12px; font-size: 12px;
padding: 3px 6px !important; padding: 3px 6px !important;
height: 26px; height: 26px;
} }
.btn { .btn {
font-size: 12px; font-size: 12px;
padding: 3px 6px; padding: 3px 6px;
height: 26px; height: 26px;
} }
.input-group-addon{ .input-group-addon {
padding: 3px 6px; padding: 3px 6px;
height: 26px; height: 26px;
font-size: 12px; font-size: 12px;
} }
.picker__select--month, .picker__select--year { .picker__select--month,
padding: 0.1em; .picker__select--year {
/*height: 3em;*/ padding: 0.1em;
/*height: 3em;*/
} }
.container { .container {
--max-width: 1024px; --max-width: 1024px;
} }
.container .info { .container .info {
font-size: 18px; font-size: 18px;
padding: 14px; padding: 14px;
color: #fff; color: #fff;
} }
.container .btn-menu { .container .btn-menu {
text-align: left; text-align: left;
font-size: 16px; font-size: 16px;
padding: 14px 24px; padding: 14px 24px;
border-radius: 6px; border-radius: 6px;
border: 0px none; border: 0px none;
width: 100%; width: 100%;
margin-bottom: 10px; margin-bottom: 10px;
} }
.container .btn-login { .container .btn-login {
font-size: 18px; font-size: 18px;
padding: 10px 20px; padding: 10px 20px;
border-radius: 6px; border-radius: 6px;
border: 0px none; border: 0px none;
background: #BC2131; background: #bc2131;
background-image: linear-gradient(to bottom, #C6414E 0px, #BC2131 100%); background-image: linear-gradient(to bottom, #c6414e 0px, #bc2131 100%);
background-repeat: repeat-x; background-repeat: repeat-x;
margin-top:20px; margin-top: 20px;
} }
.container .btn-logout { .container .btn-logout {
margin-top:12px; margin-top: 12px;
} }
.container .btn-login:hover { .container .btn-login:hover {
background: #BC2131; background: #bc2131;
} }
.container .btn-login .label { .container .btn-login .label {
display: block; display: block;
font-size: 8px; font-size: 8px;
} }
/* dataTables Customize */ /* dataTables Customize */
table.dataTable thead { table.dataTable thead {
background-color: #EAEAEA; background-color: #eaeaea;
} }
table.dataTable tr.even.selected td { table.dataTable tr.even.selected td {
background-color: #B0BED9; background-color: #b0bed9;
} }
table.dataTable tr.odd.selected td { table.dataTable tr.odd.selected td {
background-color: #9FAFD1; background-color: #9fafd1;
} }
table.dataTable tr.selected td { table.dataTable tr.selected td {
background-color: #9FAFD1; background-color: #9fafd1;
} }
/* /*
...@@ -169,7 +178,7 @@ div.tab-content { ...@@ -169,7 +178,7 @@ div.tab-content {
} }
*/ */
.form-horizontal .form-group { .form-horizontal .form-group {
margin-bottom: 4px !important; margin-bottom: 4px !important;
} }
.picker { .picker {
...@@ -189,6 +198,6 @@ div.tab-content { ...@@ -189,6 +198,6 @@ div.tab-content {
font-size: 10px !important; font-size: 10px !important;
} }
.paginate_button .current{ .paginate_button .current {
font-size: 10px !important; font-size: 10px !important;
}
\ No newline at end of file \ No newline at end of file
}
...@@ -720,6 +720,8 @@ class BaseView(object): ...@@ -720,6 +720,8 @@ class BaseView(object):
for k in cstruct: for k in cstruct:
val = cstruct.get(k) val = cstruct.get(k)
if type(val) is dict: if type(val) is dict:
if k not in value:
value[k] = {}
value[k] = self.update_value(value[k], val) value[k] = self.update_value(value[k], val)
elif val: elif val:
value[k] = cstruct.get(k) value[k] = cstruct.get(k)
...@@ -747,14 +749,7 @@ class BaseView(object): ...@@ -747,14 +749,7 @@ class BaseView(object):
e.cstruct[f.name]) e.cstruct[f.name])
if f.name == "captcha": if f.name == "captcha":
e.cstruct[f.name] = self.get_captcha_url() e.cstruct[f.name] = self.get_captcha_url()
# if e.cstruct[f.name]:
# cstruct = {}
value = self.update_value(value, e.cstruct) value = self.update_value(value, e.cstruct)
# for k in cstruct:
# if not e.cstruct.get(k):
# e.cstruct[k] = value[k]
# value.update(e.cstruct)
# value.update(cstruct)
form.set_appstruct(value) form.set_appstruct(value)
return self.returned_form(form, table, **kwargs) return self.returned_form(form, table, **kwargs)
...@@ -771,13 +766,6 @@ class BaseView(object): ...@@ -771,13 +766,6 @@ class BaseView(object):
form.set_appstruct(values) form.set_appstruct(values)
return self.returned_form(form, table, **kwargs) return self.returned_form(form, table, **kwargs)
def view_act(self, **kwargs):
if self.req.matchdict['act'] == 'grid':
if self.req.params.get("paren"):
return self.get_list(**kwargs)
return self.get_list(**kwargs)
return super().view_act(**kwargs)
def save(self, values, user, row=None): def save(self, values, user, row=None):
log.info("Save") log.info("Save")
log.debug(values) log.debug(values)
...@@ -890,7 +878,7 @@ class BaseView(object): ...@@ -890,7 +878,7 @@ class BaseView(object):
form = self.get_form(self.edit_schema, **kwargs) form = self.get_form(self.edit_schema, **kwargs)
table = self.get_item_table(row) table = self.get_item_table(row)
resources = form.get_widget_resources() values = self.get_values(row)
if request.POST: if request.POST:
if 'save' in request.POST: if 'save' in request.POST:
controls = request.POST.items() controls = request.POST.items()
...@@ -899,7 +887,14 @@ class BaseView(object): ...@@ -899,7 +887,14 @@ class BaseView(object):
controls = form.validate(controls) controls = form.validate(controls)
except ValidationFailure as e: except ValidationFailure as e:
log.error(f"Edit Error: {str(e.error.msg)}") log.error(f"Edit Error: {str(e.error.msg)}")
form.set_appstruct(e.cstruct) for f in e.field.children:
if isinstance(f.typ, colander.Date):
e.cstruct[f.name] = date_from_str(
e.cstruct[f.name])
if f.name == "captcha":
e.cstruct[f.name] = self.get_captcha_url()
values = self.update_value(values, e.cstruct)
form.set_appstruct(values)
return self.returned_form(form, table, **kwargs) return self.returned_form(form, table, **kwargs)
c = dict(controls) c = dict(controls)
...@@ -908,7 +903,6 @@ class BaseView(object): ...@@ -908,7 +903,6 @@ class BaseView(object):
return self.next_edit(form, row=row) return self.next_edit(form, row=row)
values = self.get_values(row)
form.set_appstruct(values) form.set_appstruct(values)
form = self.before_edit(form) form = self.before_edit(form)
......
...@@ -78,7 +78,10 @@ class AddSchema(colander.Schema): ...@@ -78,7 +78,10 @@ class AddSchema(colander.Schema):
missing=colander.drop, missing=colander.drop,
oid="company_id") oid="company_id")
status = colander.SchemaNode(colander.Boolean(), oid="status") status = colander.SchemaNode(
colander.Integer(),
widget=widget.CheckboxWidget(true_val='1', false_val='0'),
oid="status")
def after_bind(self, schema, kwargs): def after_bind(self, schema, kwargs):
request = kwargs["request"] request = kwargs["request"]
......
...@@ -57,9 +57,6 @@ class Login(CSRFSchema): ...@@ -57,9 +57,6 @@ class Login(CSRFSchema):
password = colander.SchemaNode( password = colander.SchemaNode(
colander.String(), widget=widget.PasswordWidget()) colander.String(), widget=widget.PasswordWidget())
# def after_bind(self, schema, kwargs): # def after_bind(self, schema, kwargs):
# request = kwargs["request"] # request = kwargs["request"]
# csrf_token = new_csrf_token(request) # csrf_token = new_csrf_token(request)
...@@ -98,6 +95,8 @@ class LoginUser(object): ...@@ -98,6 +95,8 @@ class LoginUser(object):
self.message = "Login Gagal" self.message = "Login Gagal"
set_user_log(self.message, self.request, log, values["username"]) set_user_log(self.message, self.request, log, values["username"])
return return
for g in self.user.groups:
log.debug(f"Group: {g.id} as {g.group_name}")
# generate security_code dan simpan dalam session # generate security_code dan simpan dalam session
regenerate_security_code(self.user, 0.03) # berlaku selama 1.8 menit regenerate_security_code(self.user, 0.03) # berlaku selama 1.8 menit
...@@ -115,8 +114,7 @@ class Oauth2UserExc(Exception): ...@@ -115,8 +114,7 @@ class Oauth2UserExc(Exception):
def oauth2_login(request, params=None): def oauth2_login(request, params=None):
provider_name = params and params["provider_name"] \ provider_name = params and params["provider_name"] or request.params["provider_name"]
or request.params["provider_name"]
if provider_name == "google": if provider_name == "google":
from .base_google import googlesignin from .base_google import googlesignin
try: try:
...@@ -129,8 +127,8 @@ def oauth2_login(request, params=None): ...@@ -129,8 +127,8 @@ def oauth2_login(request, params=None):
id_info = None id_info = None
iss = id_info and re.sub(r'https?://', '', id_info['iss']) or None iss = id_info and re.sub(r'https?://', '', id_info['iss']) or None
user = id_info and ExternalIdentityService. \ user = id_info and ExternalIdentityService.user_by_external_id_and_provider(
user_by_external_id_and_provider(id_info['sub'], iss) id_info['sub'], iss)
log.debug("Users : %s", user) log.debug("Users : %s", user)
log.debug("IdInfo : %s", id_info) log.debug("IdInfo : %s", id_info)
if id_info and not user: if id_info and not user:
...@@ -143,7 +141,8 @@ def oauth2_login(request, params=None): ...@@ -143,7 +141,8 @@ def oauth2_login(request, params=None):
log.debug("User : %s", user) log.debug("User : %s", user)
log.debug("Partner : %s", partner) log.debug("Partner : %s", partner)
if user or partner: if user or partner:
raise Oauth2UserExc("Email sudah terdaftar silahkan login standard") raise Oauth2UserExc(
"Email sudah terdaftar silahkan login standard")
user = User() user = User()
user.from_dict(values) user.from_dict(values)
...@@ -205,9 +204,9 @@ class ViewLogin(BaseView): ...@@ -205,9 +204,9 @@ class ViewLogin(BaseView):
# start cek external module # start cek external module
pckgs = get_params('external-uim') pckgs = get_params('external-uim')
if user: if user:
external_user = DBSession.query(ExternalIdentity) \ external_user = DBSession.query(ExternalIdentity).\
.filter_by(local_user_id=user.id, filter_by(local_user_id=user.id,
external_user_name=identity).first() external_user_name=identity).first()
pckgs = external_user and pckgs or None pckgs = external_user and pckgs or None
if pckgs: if pckgs:
...@@ -224,7 +223,8 @@ class ViewLogin(BaseView): ...@@ -224,7 +223,8 @@ class ViewLogin(BaseView):
login = LoginUser(self.req) login = LoginUser(self.req)
if not login.login(values, user): if not login.login(values, user):
request.session.flash(login.message, "error") request.session.flash(login.message, "error")
next_url = get_urls(f"{request.route_url('login')}?next={next_url}") next_url = get_urls(
f"{request.route_url('login')}?next={next_url}")
return HTTPFound(location=next_url) return HTTPFound(location=next_url)
return redirect_login(request, user) return redirect_login(request, user)
...@@ -237,8 +237,7 @@ class ViewLogin(BaseView): ...@@ -237,8 +237,7 @@ class ViewLogin(BaseView):
del request.session['login failed'] del request.session['login failed']
return r return r
elif "provider_name" in request.params and \ elif "provider_name" in request.params and request.params["provider_name"]:
request.params["provider_name"]:
try: try:
user = oauth2_login(request) user = oauth2_login(request)
except Oauth2ParseExc as e: except Oauth2ParseExc as e:
...@@ -279,6 +278,9 @@ class ViewLogin(BaseView): ...@@ -279,6 +278,9 @@ class ViewLogin(BaseView):
def redirect_login(request, user): def redirect_login(request, user):
set_user_log("Login Sukses", request, log, user.user_name) set_user_log("Login Sukses", request, log, user.user_name)
for g in user.groups:
log.debug(f"Group: {g.id} as {g.group_name}")
headers = get_login_headers(request, user) headers = get_login_headers(request, user)
request.session.flash("Sukses Login") request.session.flash("Sukses Login")
next_url = request.params.get('next') next_url = request.params.get('next')
...@@ -379,8 +381,7 @@ def view_change_password(request): ...@@ -379,8 +381,7 @@ def view_change_password(request):
code = request.matchdict['code'] code = request.matchdict['code']
q = DBSession.query(User).filter_by(security_code=code) q = DBSession.query(User).filter_by(security_code=code)
user = q.first() user = q.first()
if not user or \ if not user or create_now() - user.security_code_date > one_hour:
create_now() - user.security_code_date > one_hour:
request.session.flash('Security code expired', 'error') request.session.flash('Security code expired', 'error')
return HTTPFound(location=get_urls(request.route_url('login'))) return HTTPFound(location=get_urls(request.route_url('login')))
...@@ -436,7 +437,7 @@ class ResetPassword(colander.Schema): ...@@ -436,7 +437,7 @@ class ResetPassword(colander.Schema):
colander.String(), title=_('Email'), colander.String(), title=_('Email'),
description=_( description=_(
'email-reset-password', 'email-reset-password',
default='Enter your email address and we will send you ' \ default='Enter your email address and we will send you '
'a link to reset your password.') 'a link to reset your password.')
) )
...@@ -459,8 +460,7 @@ def send_email_security_code( ...@@ -459,8 +460,7 @@ def send_email_security_code(
**kwargs): **kwargs):
settings = get_settings() settings = get_settings()
password = kwargs.get("password", "") password = kwargs.get("password", "")
if 'mail.sender_name' not in settings \ if 'mail.sender_name' not in settings or 'mail.username' not in settings:
or 'mail.username' not in settings:
return return
url = '{}/password/{}?password={}'.format( url = '{}/password/{}?password={}'.format(
...@@ -499,8 +499,7 @@ def sending_mail(request, user, subject, body): ...@@ -499,8 +499,7 @@ def sending_mail(request, user, subject, body):
def send_email_pending( def send_email_pending(
request, user, subject, body_msg_id, body_default_file): request, user, subject, body_msg_id, body_default_file):
settings = get_settings() settings = get_settings()
if 'mail.sender_name' not in settings \ if 'mail.sender_name' not in settings or 'mail.username' not in settings:
or 'mail.username' not in settings:
return return
here = os.path.abspath(os.path.dirname(__file__)) here = os.path.abspath(os.path.dirname(__file__))
...@@ -558,4 +557,4 @@ def view_reset_password(request): ...@@ -558,4 +557,4 @@ def view_reset_password(request):
route_name='reset-password-sent', route_name='reset-password-sent',
renderer='templates/reset-password-sent.pt') renderer='templates/reset-password-sent.pt')
def view_reset_password_sent(request): def view_reset_password_sent(request):
return dict(title=_('Reset password'))
\ No newline at end of file \ No newline at end of file
return dict(title=_('Reset password'))
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
oid oid|field.oid; oid oid|field.oid;
style style|field.widget.style; style style|field.widget.style;
autofocus autofocus|field.autofocus; autofocus autofocus|field.autofocus;
url url|field.widget.url;
slave slave|field.widget.slave; slave slave|field.widget.slave;
url url|field.widget.url;
" tal:omit-tag=""> " tal:omit-tag="">
${field.start_mapping()} ${field.start_mapping()}
<input type="hidden" name="auto_id" id="${oid}-auto_id" value="${auto_id}" /> <input type="hidden" name="auto_id" id="${oid}-auto_id" value="${auto_id}" />
...@@ -28,15 +28,22 @@ ...@@ -28,15 +28,22 @@
var not_check = ["id", "value"]; var not_check = ["id", "value"];
$.each(datum, function (key, val) { $.each(datum, function (key, val) {
if (!not_check.includes(key)) { if (!not_check.includes(key)) {
var ele = $('#' + key); var eleName = $('#' + key).prop('nodeName');
if (ele !== undefined) {
var eleName = ele.prop('nodeName').toLowerCase(); if (eleName !== undefined) {
eleName = eleName.toLowerCase();
if (eleName === "select") if (eleName === "select")
$("#" + key).val(val).trigger("change"); $("#" + key).val(val).trigger("change");
else if (eleName === "input") else if (eleName === "input")
$("#" + key).val(val); $("#" + key).val(val);
else else
$("#" + key).text(val); $("#" + key).text(val);
} else {
//Check apakah jika radio button
eleName = $("input[name ='" + key + "']").prop('type');
if (eleName == "radio") {
$("input[name ='" + key + "'][value='" + val + "']").prop('checked', true);
}
} }
} }
}); });
......
...@@ -265,6 +265,8 @@ class DeTable(field.Field): ...@@ -265,6 +265,8 @@ class DeTable(field.Field):
d["action"] = f.action d["action"] = f.action
else: else:
d["action"] = True d["action"] = True
if hasattr(f, "search_method"):
d["search_method"] = f.search_method
if isinstance(f.widget, deform_widget.HiddenWidget): if isinstance(f.widget, deform_widget.HiddenWidget):
d["visible"] = False d["visible"] = False
...@@ -441,18 +443,27 @@ class DeTable(field.Field): ...@@ -441,18 +443,27 @@ class DeTable(field.Field):
html += '</select>' html += '</select>'
elif isinstance(f.typ, colander.Date): elif isinstance(f.typ, colander.Date):
html += f'<div class="form-group" {txt}>' search_method = getattr(f, "search_method", None)
html += f'<label class="form-label" style="font-size:12px">{f.title}</label>' if search_method == "date":
html += f'<div class="input-group input-daterange" style="padding: 3px 0px 7px !important;">' # html += f'<div class="tooltip">'
html += f'<input type="date" class="form-control {self.tableid}-control-filter hasDatePicker"' html += f'<label class="form-label" style="font-size:12px">{f.title}</label>'
html += f'data-index={field_index} placeholder="{f.title} Awal"' html += f'<input type="date" class="form-control {self.tableid}-control-filter"'
html += f'name="{col_id}" id="{col_id}-min"/>' html += f'{txt}/>'
html += f'<div class="input-group-addon">-</div>' # html += f'<span class="tooltiptext">{f.title}</span>'
html += f'<input type="date" class="form-control {self.tableid}-control-filter hasDatePicker"' # html += f'</div>'
html += f'data-index={field_index} placeholder="{f.title} Akhir" ' else:
html += f'name="{col_id}" id="{col_id}-max" /></span>' html += f'<div class="form-group" {txt}>'
html += f'</div>' html += f'<label class="form-label" style="font-size:12px">{f.title}</label>'
html += f'</div>' html += f'<div class="input-group input-daterange" style="padding: 3px 0px 7px !important;">'
html += f'<input type="date" class="form-control {self.tableid}-control-filter hasDatePicker"'
html += f'data-index={field_index} placeholder="{f.title} Awal"'
html += f'name="{col_id}" id="{col_id}-min"/>'
html += f'<div class="input-group-addon">-</div>'
html += f'<input type="date" class="form-control {self.tableid}-control-filter hasDatePicker"'
html += f'data-index={field_index} placeholder="{f.title} Akhir" '
html += f'name="{col_id}" id="{col_id}-max" /></span>'
html += f'</div>'
html += f'</div>'
""" """
awal awal
html += f'<div class="form-group" {txt}>' html += f'<div class="form-group" {txt}>'
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!