Commit 25e2a5fb by aa.gusti

Perubahan Route

1 parent 72ebe4ad
4.0.0 17-11-2024
Penambahan Field pada tabel routes
Tabel Routes berfungsi juga sebagai menu generator
4.0.0 09-07-2024
Perubahan Colander>2.0
Perubahan SQLAlchemy>2.0
......@@ -167,4 +171,4 @@ Penambahan custom render
0.0
---
- Initial version
- Initial version
\ No newline at end of file
......@@ -156,7 +156,18 @@ Contoh::
</Proxy>
</VirtualHost>
```
# Migrasi
Karena ada penambahan dari fungsi table route berfungsi sebagai menu
generator, maka diperlukan upgrade khusus bagi aplikasi lama
```
alembic -c config_file -n alembic_models upgrade head
```
Tambahkan Konfigurasi berikut ini
```
[alembic_models]
sqlalchemy.url = postgresql://user:password@localhost:5432/db
script_location = opensipkd.models:alembic
```
# Virtual Directory
## Setting Ini File
......@@ -223,4 +234,4 @@ trusted_proxy_count = 1
trusted_proxy_headers = x-forwarded-for x-forwarded-host x-forwarded-proto x-forwarded-port
clear_untrusted_proxy_headers = yes
url_scheme = https # HTTP or https
```
```
\ No newline at end of file
......@@ -62,6 +62,7 @@ static_route = [
]
# http://stackoverflow.com/questions/9845669/pyramid-inverse-to-add-notfound-viewappend-slash-true
# class RemoveSlashNotFoundViewFactory(object):
# diganti menggunakan @view_config(context=HTTPNotFound, renderer='templates/404.pt') pada base.views
......@@ -155,6 +156,8 @@ def add_global(event):
event['get_urls'] = get_urls
event['get_csrf_token'] = get_csrf_token
event['get_params'] = get_params
event['get_module_menus'] = get_module_menus
event['get_module_submenus'] = get_module_submenus
def get_params(request, params, alternate=None, settings=None):
......@@ -424,8 +427,8 @@ def get_home(request):
return request.route_url('home')[:-1]
def set_routes(config, app_id=None):
q = DBSession.query(Route)
def _set_routes1(config, app_id):
q = DBSession.query(Route).filter(Route.path != None, Route.module == None, Route.status==1)
if not app_id:
q.filter(or_(Route.app_id == 0, None == Route.app_id))
else:
......@@ -441,6 +444,58 @@ def set_routes(config, app_id=None):
default_renderer="json_rpc")
def _set_routes2(config, module="base"):
q = DBSession.query(Route).filter(Route.module == module, Route.status==1)
for route in q:
if route.type == 0:
config.add_route(route.kode, route.path)
if route.nama:
titles[route.kode] = route.nama
elif route.type == 1:
config.add_jsonrpc_endpoint(route.kode, route.path,
default_renderer="json_rpc")
return q
def set_routes(config, app_id=None):
if app_id and type(app_id) == str:
return _set_routes2(config, app_id)
else:
return _set_routes1(config, app_id)
def get_route_names(rows):
return [r.kode for r in rows if not r.is_menu]
def get_children(rows):
return [{"id": r.id, "path": r.path, "nama": r.nama, "is_menu": r.is_menu,
"icon": r.icon,
"route_names": [r.kode] + get_route_names(r.children),
"children": get_children(r.children),
"has_sub": r.path.find("/") == -1
}
for r in rows if r.is_menu and r.status==1]
def get_module_menus(module):
query = DBSession.query(Route) \
.filter(Route.module == module,
Route.is_menu == 1,
Route.parent_id == None)
result = get_children(query.order_by(Route.order_id))
log.debug(result)
return result
def get_module_submenus(parent_id):
q = DBSession.query(Route) \
.filter(Route.parent_id == parent_id) \
.order_bY(Route.order_id)
return [r.kode for r in query.all()]
partner_idcard_url = 'partner/idcard'
......@@ -451,7 +506,8 @@ def main(global_config, **settings):
None: {"js": "opensipkd.base:static/jquery/jquery.maskMoney.min.js"}}
engine = engine_from_config(
settings, 'sqlalchemy.', client_encoding='utf8', max_identifier_length=30) # , convert_unicode=True
settings, 'sqlalchemy.', client_encoding='utf8',
max_identifier_length=30) # , convert_unicode=True
DBSession.configure(bind=engine)
LogDBSession.configure(bind=engine)
Base.metadata.bind = engine
......@@ -512,6 +568,10 @@ def main(global_config, **settings):
config.add_request_method(get_params, 'get_params', reify=True)
config.add_request_method(get_csrf_token, 'get_csrf_token', reify=True)
# Penambahan Module Auto Generate Menu
# config.add_request_method(get_module_menus, 'get_module_menus', reify=True)
# config.add_request_method(get_module_submenus, 'get_module_submenus', reify=True)
# config.add_translation_dirs('opensipkd.base:locale/')
config.add_static_view('static', 'opensipkd.base:static',
......@@ -546,4 +606,4 @@ def main(global_config, **settings):
for m in modules:
config.scan(m)
return config.make_wsgi_app()
return config.make_wsgi_app()
\ No newline at end of file
......@@ -242,6 +242,8 @@ def append_csv(table, filename, keys, get_file_func=get_file,
value = cf[fname]
fname_orig = fmap[fname]
if not value and callback:
value = callback("value", data=cf, field=fname_orig)
data[fname_orig] = value
for key in keys:
......@@ -279,6 +281,7 @@ def append_csv(table, filename, keys, get_file_func=get_file,
# update: tambah periksa nilai default.
# Jika default=None berarti wajib ada nilainya
# by tatang 2024-10-12
log.debug(data)
raise Exception(
f"Table {str(table.__name__)} Field '{c['name']}' wajib ada {c['type']} ")
......
......@@ -159,12 +159,11 @@ class BaseView(object):
self.upload_keys = ["kode"]
self.report_file = ""
self.new_buttons = {}
self.is_object = False
def query_register(self, **kwargs):
pass
def route_list(self, **kwargs):
msg = kwargs.get("msg")
error = kwargs.get("error", "")
......@@ -274,7 +273,7 @@ class BaseView(object):
resources = form.get_widget_resources()
readonly = "readonly" in kwargs and kwargs["readonly"] or False
kwargs["readonly"] = readonly
is_object = kwargs.get("is_object")
is_object = kwargs.get("is_object", self.is_object)
if is_object:
return dict(form=form,
table=table and table.render() or None,
......@@ -520,7 +519,7 @@ class BaseView(object):
form = self.get_form(self.add_schema, **kwargs)
table = self.get_item_table(**kwargs)
resources = form.get_widget_resources()
is_object = kwargs.get("is_object", False)
is_object = kwargs.get("is_object", self.is_object)
if self.req.POST:
if 'save' in self.req.POST:
controls = self.req.POST.items()
......@@ -621,7 +620,7 @@ class BaseView(object):
def view_edit(self, **kwargs):
request = self.req
row = self.query_id().first()
is_object = kwargs.get("is_object", False)
is_object = kwargs.get("is_object", self.is_object)
if not row:
return self.id_not_found(**kwargs)
......@@ -673,7 +672,7 @@ class BaseView(object):
request = self.req
q = self.query_id()
row = q.first()
is_object = kwargs.get("is_object", False)
is_object = kwargs.get("is_object", self.is_object)
if not row:
return self.id_not_found()
if not self.bindings:
......
......@@ -96,8 +96,10 @@ class EditSchema(AddSchema):
class ListSchema(colander.Schema):
id = colander.SchemaNode(colander.Integer(),
title=_("action", default="Action"))
module= colander.SchemaNode(colander.String(), title="Kode", width='100pt')
kode = colander.SchemaNode(colander.String(), title="Kode", width='100pt')
nama = colander.SchemaNode(colander.String(), title="Nama")
permission = colander.SchemaNode(colander.String(), title="Permission")
status = colander.SchemaNode(colander.Boolean(), title="Status",
width='50pt')
need_login = colander.SchemaNode(colander.Integer(), title="Login",
......@@ -232,4 +234,4 @@ class ViewMenus(BaseView):
@view_config(route_name='menu-delete',
renderer='templates/form.pt', permission='menu')
def view_delete(self):
return super(ViewMenus, self).view_delete()
return super(ViewMenus, self).view_delete()
\ No newline at end of file
......@@ -20,6 +20,7 @@
desa_path ['desa', 'desa-add', 'desa-edit', 'desa-view', 'desa-delete'];
css css|[];
js js|[];
route_name route_name|request.matched_route.name;
">
<head>
......@@ -159,64 +160,64 @@
<a href="#"><i class="fa fa-lg fa-fw fa-shield"></i><span class="menu-item-parent">Admin</span></a>
<ul>
<li tal:condition="has_permission(request, ['user-view', 'user-edit'])"
tal:attributes="class request.matched_route.name in user_path and 'active'">
tal:attributes="class route_name in user_path and 'active'">
<a href="${home}/user">User</a>
</li>
<li tal:condition="has_permission(request, ['user-view', 'user-edit'])"
tal:attributes="class request.matched_route.name in user_area_path and 'active'">
tal:attributes="class route_name in user_area_path and 'active'">
<a href="${home}/user/area">User Area</a>
</li>
<li tal:condition="has_permission(request, ['user-view', 'user-edit'])"
tal:attributes="class request.matched_route.name in user_dep_path and 'active'">
tal:attributes="class route_name in user_dep_path and 'active'">
<a href="${home}/user/departemen">User Departemen</a>
</li>
<li tal:condition="has_permission(request, ['user-view', 'user-edit'])"
tal:attributes="class request.matched_route.name in user_ext_path and 'active'">
tal:attributes="class route_name in user_ext_path and 'active'">
<a href="${home}/user/ext">External User</a>
</li>
<li tal:condition="has_permission(request, ['user-view', 'user-edit'])"
tal:attributes="class request.matched_route.name in group_path and 'active'">
tal:attributes="class route_name in group_path and 'active'">
<a href="${home}/group">Group</a>
</li>
<li tal:condition="has_permission(request, 'upload-logo')"
tal:attributes="class request.matched_route.name in ['upload-logo'] and 'active'">
tal:attributes="class route_name in ['upload-logo'] and 'active'">
<a href="${home}/upload/logo">Upload Logo</a></li>
<li tal:condition="has_permission(request, 'parameter')"
tal:attributes="class request.matched_route.name in param_path and 'active'">
tal:attributes="class route_name in param_path and 'active'">
<a href="${home}/parameter">Parameter</a></li>
<li tal:condition="has_permission(request, 'company')"
tal:attributes="class request.matched_route.name in company_path and 'active'">
tal:attributes="class route_name in company_path and 'active'">
<a href="${home}/company">Pemerintah</a></li>
<li tal:condition="has_permission(request, 'eselon')"
tal:attributes="class request.matched_route.name in eselon_path and 'active'">
tal:attributes="class route_name in eselon_path and 'active'">
<a href="${home}/eselon">Eselon</a></li>
<li tal:condition="has_permission(request, 'jabatan')"
tal:attributes="class request.matched_route.name in jabatan_path and 'active'">
tal:attributes="class route_name in jabatan_path and 'active'">
<a href="${home}/jabatan">Jabatan</a></li>
<li tal:condition="has_permission(request, 'departemen')"
tal:attributes="class request.matched_route.name in dep_path and 'active'">
tal:attributes="class route_name in dep_path and 'active'">
<a href="${home}/departemen">Departemen</a></li>
<li tal:condition="has_permission(request, 'partner')"
tal:attributes="class request.matched_route.name in partner_path and 'active'">
tal:attributes="class route_name in partner_path and 'active'">
<a href="${home}/partner">Partner</a></li>
<li tal:condition="has_permission(request, 'partner-departemen')"
tal:attributes="class request.matched_route.name in part_dep_path and 'active'">
tal:attributes="class route_name in part_dep_path and 'active'">
<a href="${home}/partner/departemen">Partner Departemen</a></li>
<li tal:condition="has_permission(request, 'provinsi')"
tal:attributes="class request.matched_route.name in provinsi_path and 'active'">
tal:attributes="class route_name in provinsi_path and 'active'">
<a href="${home}/provinsi">Provinsi</a></li>
<li tal:condition="has_permission(request, 'dati2')"
tal:attributes="class request.matched_route.name in dati2_path and 'active'">
tal:attributes="class route_name in dati2_path and 'active'">
<a href="${home}/dati2">Kabupaten/Kota</a></li>
<li tal:condition="has_permission(request, 'kecamatan')"
tal:attributes="class request.matched_route.name in kecamatan_path and 'active'">
tal:attributes="class route_name in kecamatan_path and 'active'">
<a href="${home}/kecamatan">Kecamatan</a></li>
<li tal:condition="has_permission(request, 'desa')"
tal:attributes="class request.matched_route.name in desa_path and 'active'">
tal:attributes="class route_name in desa_path and 'active'">
<a href="${home}/desa">Desa/Kelurahan</a></li>
<li tal:condition="has_permission(request, 'log')"
tal:attributes="class request.matched_route.name in ['log'] and 'active'">
tal:attributes="class route_name in ['log'] and 'active'">
<a href="${home}/log">Log</a></li>
</ul>
......@@ -338,4 +339,4 @@
<!-- Define Script-->
<script metal:define-slot="scripts"></script>
</body>
</html>
</html>
\ No newline at end of file
......@@ -24,7 +24,7 @@ def table_has_column(table, column, schema=None):
return has_column
def fields_update(table, field, typ, schema="pad"):
def fields_update(table, field, typ, schema="public"):
context = op.get_context()
helpers = context.opts['helpers']
if not helpers.table_has_column(table, field, schema):
......
"""create table
"""ugrade routes
Revision ID: 1a608edd4715
Revises:
......@@ -17,8 +17,19 @@ import sqlalchemy as sa
def upgrade():
pass
schema = "public"
context = op.get_context()
helpers = context.opts['helpers']
helpers.fields_update("routes", "module", sa.String(256), schema)
helpers.fields_update("routes", "is_menu", sa.SmallInteger, schema)
helpers.fields_update("routes", "parent_id", sa.Integer, schema)
helpers.fields_update("routes", "order_id", sa.Integer, schema)
helpers.fields_update("routes", "permission", sa.String(256), schema)
helpers.fields_update("routes", "class_view", sa.String(256), schema)
helpers.fields_update("routes", "def_func", sa.String(256), schema)
helpers.fields_update("routes", "template", sa.String(256), schema)
helpers.fields_update("routes", "icon", sa.String(256), schema)
def downgrade():
pass
pass
\ No newline at end of file
......@@ -10,11 +10,23 @@ from .users import User
class Route(Base, NamaModel):
__tablename__ = 'routes'
__table_args__ = {'extend_existing': True}
id = Column(Integer, primary_key=True)
kode = Column(String(128), unique=True)
path = Column(String(256), nullable=False, unique=True)
status = Column(Integer, nullable=False, server_default='1')
type = Column(SmallInteger, nullable=False, server_default='0')
app_id = Column(SmallInteger, nullable=False, server_default='0')
module = Column(String(256))
is_menu = Column(SmallInteger)
parent_id = Column(Integer, ForeignKey("routes.id"))
order_id = Column(Integer)
permission = Column(String(256))
class_view = Column(String(256))
def_func = Column(String(256))
template = Column(String(256))
icon = Column(String(256))
children = relationship(
"Route", backref=backref('parent', remote_side=[id]))
class Parameter(Base, NamaModel):
......@@ -53,4 +65,4 @@ class ResCompany(Base, NamaModel):
parent = relationship(
"ResCompany", remote_side=[id], primaryjoin="ResCompany.parent_id==ResCompany.id",
overlaps="children"
)
)
\ No newline at end of file
......@@ -3,7 +3,7 @@ from sqlalchemy import (
Integer,
ForeignKey,
String,
SmallInteger, Boolean,
SmallInteger, Boolean,Text
)
from sqlalchemy.orm import (
relationship,
......@@ -19,9 +19,9 @@ class Menus(Base, NamaModel):
__tablename__ = 'menus'
__table_args__ = (TABLE_ARGS,)
id = Column(Integer, primary_key=True)
order_id = Column(SmallInteger)
parent_id = Column(Integer, ForeignKey('public.menus.id'))
level_id = Column(SmallInteger)
order_id = Column(SmallInteger)
valu = Column(String(256)) # value/action
meth = Column(String(256)) # new method
page_typ = Column(String(256)) # PageType
......@@ -73,4 +73,4 @@ class Menus(Base, NamaModel):
else:
row = cls.query().filter(cls.kode == parent).first()
if row:
return cls.query().filter(cls.parent_id == row.id)
return cls.query().filter(cls.parent_id == row.id)
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!