Commit 80af18808723e2fc3122f0d084f928cf4008b67e

Authored by Василь Свідрик
1 parent d5c5c41c67
Exists in master

add stable version

Showing 47 changed files with 579 additions and 265 deletions Inline Diff

__pycache__/app.cpython-310.pyc
No preview for this file type
__pycache__/routes.cpython-310.pyc
No preview for this file type
1 from flask_cors import CORS 1 from flask_cors import CORS
2 from flask_babel import Babel 2 from flask_babel import Babel
3 from flask_jwt_extended import JWTManager 3 from flask_jwt_extended import JWTManager
4 #from k2.k2rout import * 4 #from k2.k2rout import *
5 from flask import Flask 5 from flask import Flask
6 from k2.k2cfg import k2 6 from k2.k2cfg import k2
7 7
8 8
9 9
10 # configure flask app 10 # configure flask app
11 app = Flask(__name__) 11 app = Flask(__name__)
12 app.config['SECRET_KEY'] = k2.secret_key 12 app.config['SECRET_KEY'] = k2.secret_key
13 app.json.sort_keys = k2.json_sort_keys 13 app.json.sort_keys = k2.json_sort_keys
14 #app.config.from_object(k2) 14 #app.config.from_object(k2)
15 15
16 16
17 # init db 17 # init db
18 k2().init_db(app) 18 k2().init_db(app)
19 CORS(app) 19 CORS(app)
20 jwt = JWTManager(app)
21 20
21
22 #translate 22 #translate
23 k2.load_babel_translation_directories() 23 k2.load_babel_translation_directories()
24 app.config['BABEL_TRANSLATION_DIRECTORIES'] = k2.babel_translation_directories 24 app.config['BABEL_TRANSLATION_DIRECTORIES'] = k2.babel_translation_directories
25 app.config['BABEL_DEFAULT_LOCALE'] = k2.default_language 25 app.config['BABEL_DEFAULT_LOCALE'] = k2.default_language
26 app.config['BABEL_LANGUAGES'] = { 26 app.config['BABEL_LANGUAGES'] = k2.languages
27 'en': 'English',
28 'uk': 'Українська',
29 'pl': 'Polski'
30 }
31 app.config['BABEL_DEFAULT_TIMEZONE'] = k2.timezone 27 app.config['BABEL_DEFAULT_TIMEZONE'] = k2.timezone
32 babel = Babel(app) 28 babel = Babel(app)
33 babel.init_app(app, locale_selector=k2.get_locale) 29 babel.init_app(app, locale_selector=k2.get_locale)
30
31 #menu
32 @app.context_processor
33 def inject_static_variable():
34 return {'menu': k2.menu}
34 35
35 # flask routing 36 # flask routing
36 from routes import * 37 from routes import *
37 38
38 if __name__ == '__main__': 39 if __name__ == '__main__':
39 app.run() 40 app.run()
40 41
41 42
42 43
components/k2test/.idea/.gitignore
1 # Default ignored files File was deleted
2 /shelf/
3 /workspace.xml
4 1 # Default ignored files
components/k2test/.idea/gittest.iml
1 <?xml version="1.0" encoding="UTF-8"?> File was deleted
2 <module type="PYTHON_MODULE" version="4">
3 <component name="NewModuleRootManager">
4 <content url="file://$MODULE_DIR$">
5 <excludeFolder url="file://$MODULE_DIR$/venv" />
6 </content>
7 <orderEntry type="inheritedJdk" />
8 <orderEntry type="sourceFolder" forTests="false" />
9 </component>
10 </module>
components/k2test/.idea/inspectionProfiles/profiles_settings.xml
1 <component name="InspectionProjectProfileManager"> File was deleted
2 <settings>
3 <option name="USE_PROJECT_PROFILE" value="false" />
4 <version value="1.0" />
5 </settings>
6 </component>
components/k2test/.idea/misc.xml
1 <?xml version="1.0" encoding="UTF-8"?> File was deleted
2 <project version="4">
3 <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (gittest)" project-jdk-type="Python SDK" />
4 <component name="PyCharmProfessionalAdvertiser">
5 <option name="shown" value="true" />
6 </component>
7 </project>
components/k2test/.idea/modules.xml
1 <?xml version="1.0" encoding="UTF-8"?> File was deleted
2 <project version="4">
3 <component name="ProjectModuleManager">
4 <modules>
5 <module fileurl="file://$PROJECT_DIR$/.idea/gittest.iml" filepath="$PROJECT_DIR$/.idea/gittest.iml" />
6 </modules>
7 </component>
8 </project>
components/k2test/.idea/vcs.xml
1 <?xml version="1.0" encoding="UTF-8"?> File was deleted
2 <project version="4">
3 <component name="VcsDirectoryMappings">
4 <mapping directory="$PROJECT_DIR$" vcs="Git" />
5 </component>
6 </project>
components/k2test/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2test/history.txt
1 1.0.0.0 base component File was deleted
2 1.0.0.1 add some routes
components/k2test/k2test/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2test/k2test/__pycache__/views.cpython-310.pyc
No preview for this file type
components/k2test/k2test/languages/en/LC_MESSAGES/messages.mo
No preview for this file type
components/k2test/k2test/languages/en/LC_MESSAGES/messages.po
1 msgid "New 2 page" File was deleted
2 msgstr "Нова сторінка 2"
3 msgid "title_menu_items"
4 msgstr "Test menu items"
components/k2test/k2test/languages/uk/LC_MESSAGES/messages.mo
No preview for this file type
components/k2test/k2test/languages/uk/LC_MESSAGES/messages.po
1 msgid "New 2 page" File was deleted
2 msgstr "Нова сторінка 2"
3 msgid "title_menu_items"
4 msgstr "Тестова компонента"
components/k2test/k2test/templates/new2.html
1 File was deleted
2
3 <h2>{{ _('New 2 page') }}</h2>
components/k2test/k2test/views.py
1 from flask import render_template, redirect, request, jsonify File was deleted
2 from flask_babel import gettext
3 from flask_login import login_user, current_user, logout_user, login_required
4 from flask import current_app as k2
5 from flask import Blueprint, json
6 from flask_sqlalchemy import SQLAlchemy
7
8
9 #bliueprint
10 k2test = Blueprint('k2test', __name__, template_folder='templates', static_folder='static')
11
12 #component routes
13 @k2test.route('/new')
14 def new_component():
15 db = k2.extensions['sqlalchemy'].db
16 connection = db.engine.connect()
17 query = db.text("SELECT email, login FROM k2users")
18 result = connection.execute(query).fetchall()
19 rows = [dict(email=row.email, login=row.login) for row in result]
20 # Перетворення результату на JSON
21 json_result = json.dumps(rows)
22 return json_result
23
24 @k2test.route('/new2')
25 def new_component2():
26 return render_template('new2.html')
27
28 @k2test.route('/new3')
29 def new_component3():
30 return jsonify({'data': 'page new3'})
31
32 @k2test.route('/new4')
33 def new_component4():
34 return jsonify({'data': 'page new4'})
35
36 # menu items for admin
37 @k2test.route('/menu-admin-items')
38 def menu_items():
39 data = [
40 {
41 'title': 'Test items',
42 'icon': {'icon': 'mdi-chart-timeline-variant'},
43 'children': [
44 {'title': 'Test 3', 'to': 'k2test-new3'},
45 {'title': 'Test 4', 'to': 'k2test-new4'},
46 {'title': 'Test 5', 'to': 'k2test-new5'},
47 {'title': 'Test 6', 'to': 'k2test-new6'},
48 {'title': 'Test 7', 'to': 'k2test-new7'}
49 ],
50 }
51
52 ]
53 return data
54 1 from flask import render_template, redirect, request, jsonify
55 2 from flask_babel import gettext
components/k2test/requirements.txt
1 Flask-Login==0.6.2 File was deleted
2 1 Flask-Login==0.6.2
components/k2test/setup.py
1 from setuptools import setup, find_packages File was deleted
2
3 setup(
4 name='k2test',
5 version='1.0.0',
6 description='Description of my project',
7 author='k2 cloud',
8 author_email='rs@corp2.net',
9 keywords="k2test, k2",
10 python_requires=">=3.7, <=3.11.2",
11 packages=['k2test'],
12 package_data={ # Optional
13 },
14 install_requires=[""],
15 )
16 1 from setuptools import setup, find_packages
No preview for this file type
k2/__pycache__/k2cfg.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2obj.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2rout.cpython-310.pyc
No preview for this file type
1 from flask_sqlalchemy import SQLAlchemy 1 from flask_sqlalchemy import SQLAlchemy
2 from sqlalchemy import text 2 from sqlalchemy import text
3 from .k2obj import k2obj 3 from .k2obj import k2obj
4 import yaml 4 import yaml
5 import os 5 import os
6 import requests 6 import requests
7 import pytz 7 import pytz
8 import os 8 import os
9 import sys 9 import sys
10 from flask import session 10 from flask import session, request
11 from flask_login import LoginManager
11 12
12 13
13
14 class k2(k2obj): 14 class k2(k2obj):
15 version = '2.5.1.27' 15 version = '2.5.1.27'
16 db = SQLAlchemy() 16 db = SQLAlchemy()
17 domain = 'http://127.0.0.1:5000/' 17 domain = 'http://127.0.0.1:5000/'
18 update_domain ='http://185.174.172.137/' 18 update_domain = 'http://127.0.0.1:8000/' #'http://185.174.172.137/'
19 venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/Scripts') 19 venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/Scripts') #for windows
20 #venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/bin') #for linux
20 json_sort_keys = False 21 json_sort_keys = False
21 timezone = pytz.timezone('Europe/Kiev') 22 timezone = pytz.timezone('Europe/Kiev')
22 secret_key = 'JH&INH987gFDHdsagh&8dwbjdw8ckw' 23 secret_key = 'JH&INH987gFDHdsagh&8dwbjdw8ckw'
23 default_language = 'en' 24 default_language = 'en'
24 current_language = '' 25 current_language = ''
25 babel_translation_directories = '' 26 babel_translation_directories = ''
27 languages = {
28 'en': 'English',
29 'uk': 'Українська',
30 'pl': 'Polski'
31 }
26 components = '' 32 components = ''
33 login_manager = LoginManager()
27 34
28 35
29 36
37
30 def __init__(self): 38 def __init__(self):
31 super().__init__() 39 super().__init__()
32 40
33 @classmethod 41 @classmethod
34 def load_babel_translation_directories(cls): 42 def load_babel_translation_directories(cls):
35 with open('languages/babel_translation_directories.yml', 'r') as f: 43 with open('languages/babel_translation_directories.yml', 'r') as f:
36 data = yaml.safe_load(f) 44 data = yaml.safe_load(f)
37 print(data['babel_translation_directories']) 45 #print(data['babel_translation_directories'])
38 cls.babel_translation_directories = data['babel_translation_directories'] 46 cls.babel_translation_directories = data['babel_translation_directories']
39 47
40 @classmethod 48 @classmethod
41 def get_locale(cls): 49 def get_locale(cls):
42 if 'lang' in session: 50 if 'lang' in session:
43 # Отримати обрану мову з сеансу користувача 51 # Отримати обрану мову з сеансу користувача
44 return session['lang'] 52 return session['lang']
45 else: 53 else:
46 # Повернути мову за замовчуванням з налаштувань додатку 54 # Повернути мову за замовчуванням з налаштувань додатку
47 return cls.default_language #app.config['DEFAULT_LANGUAGE'] 55 return cls.default_language #app.config['DEFAULT_LANGUAGE']
48 56
49 @classmethod 57 @classmethod
50 def search_babel_translation_directories(cls): 58 def search_babel_translation_directories(cls):
51 response = requests.get(f'{cls.domain}api/languages') 59 response = requests.get(f'{cls.domain}api/languages')
52 if response.status_code == 200: 60 if response.status_code == 200:
53 cls.babel_translation_directories = response.text 61 cls.babel_translation_directories = response.text
54 data = {'babel_translation_directories': response.text} 62 data = {'babel_translation_directories': response.text}
55 else: 63 else:
56 cls.babel_translation_directories = 'languages' 64 cls.babel_translation_directories = 'languages'
57 data = {'babel_translation_directories': 'languages'} 65 data = {'babel_translation_directories': 'languages'}
58 66
59 with open('languages/babel_translation_directories.yml', 'w') as f: 67 with open('languages/babel_translation_directories.yml', 'w') as f:
60 yaml.dump(data, f) 68 yaml.dump(data, f)
61 69
70
71
62 # load database settings from yml file 72 # load database settings from yml file
63 def init_db_uri(self): 73 def init_db_uri(self):
64 with open('db/db.yml', 'r') as f: 74 with open('db/db.yml', 'r') as f:
65 db_config = yaml.load(f, Loader=yaml.FullLoader) 75 db_config = yaml.load(f, Loader=yaml.FullLoader)
66 return db_config 76 return db_config
67 77
68 # creating a connection 78 # creating a connection
69 def init_db(self, app): 79 def init_db(self, app):
70 db_config = self.init_db_uri() 80 db_config = self.init_db_uri()
71 db_uri = f"mysql+{db_config['driver']}://{db_config['user']}:{db_config['password']}@{db_config['host']}/{db_config['dbname']}" 81 db_uri = f"mysql+{db_config['driver']}://{db_config['user']}:{db_config['password']}@{db_config['host']}/{db_config['dbname']}"
72 app.config['SQLALCHEMY_DATABASE_URI'] = db_uri 82 app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
73 db_path = '../db/database.db' 83 db_path = '../db/database.db'
74 app.config['SQLALCHEMY_BINDS'] = {'db2': f'sqlite:///{db_path}'} 84 app.config['SQLALCHEMY_BINDS'] = {'db2': f'sqlite:///{db_path}'}
75 self.db.init_app(app) 85 self.db.init_app(app)
86
87 def init_lm(self, app):
88 # Initialize LoginManager
89 self.login_manager.init_app(app)
76 90
77 91
1 class k2obj: 1 class k2obj:
2 name = '' 2 name = ''
3 version = '' 3 version = ''
4 domain = '' 4 domain = ''
5 timezone = '' 5 timezone = ''
6 menu = '' 6 menu = ''
7 permissions = { 7 permissions = {
8 'r': '0', 8 'r': '0',
9 'w': '0', 9 'w': '0',
10 'i': '0', 10 'i': '0',
11 'd': '0', 11 'd': '0',
12 'c': '0', 12 'c': '0',
13 'exp': '0', 13 'exp': '0',
14 'imp': '0', 14 'imp': '0',
15 'settable': '0', 15 'settable': '0',
16 'cutpast': '0', 16 'cutpast': '0',
17 'enable': '0' 17 'enable': '0'
18 } 18 }
19 languages = ''
19 components = '' 20 components = ''
20 21
21 22
22 23
23 24
24 25
25 26
1 import zipfile 1 import zipfile
2 from flask import Flask, Blueprint, jsonify, render_template, redirect, url_for, session, jsonify 2 from flask import Flask, Blueprint, jsonify, render_template, redirect, url_for, session, jsonify
3 import os 3 import os
4 import shutil 4 import shutil
5 from flask import request 5 from flask import request
6 from .k2cfg import k2 6 from .k2cfg import k2
7 from .k2comp import Component 7 from .k2comp import Component
8 from flask_migrate import Migrate 8 from flask_migrate import Migrate
9 import requests 9 import requests
10 import subprocess 10 import subprocess
11 from flask import current_app 11 from flask import current_app
12 import yaml 12 import yaml
13 from functools import wraps 13 from functools import wraps
14 import os 14 import os
15 import sys 15 import sys
16 from .k2admmenu import K2admin_menus, K2admin_Menus_Prava 16 from .k2admmenu import K2admin_menus, K2admin_Menus_Prava
17 from sqlalchemy import text 17 from sqlalchemy import text
18 from flask_jwt_extended import get_jwt_identity, jwt_required 18 from flask_jwt_extended import get_jwt_identity, jwt_required
19 from flask_login import login_user, current_user, logout_user, login_required
19 20
20 21
21
22 # initialize db 22 # initialize db
23 # migrate = Migrate(app, db) 23 # migrate = Migrate(app, db)
24 24
25 components_bp = Blueprint('components', __name__, template_folder='templates') 25 components_bp = Blueprint('components', __name__, template_folder='templates')
26 config = yaml.safe_load(open("db/first-login.yml")) 26 config = yaml.safe_load(open("db/first-login.yml"))
27 27
28 db = k2.db 28 db = k2.db
29 29
30 30
31 def first_login_required(view_func): 31 def first_login_required(view_func):
32 @wraps(view_func) 32 @wraps(view_func)
33 def decorated_view(*args, **kwargs): 33 def decorated_view(*args, **kwargs):
34 if 'username' not in session: 34 if 'username' not in session:
35 return redirect(url_for('components.first_login')) 35 return redirect(url_for('components.first_login'))
36 return view_func(*args, **kwargs) 36 return view_func(*args, **kwargs)
37 37
38 return decorated_view 38 return decorated_view
39 39
40 # def append_to_yaml_file(file_path, data): 40 # def append_to_yaml_file(file_path, data):
41 # with open(file_path, 'r') as f: 41 # with open(file_path, 'r') as f:
42 # existing_data = yaml.safe_load(f) or [] 42 # existing_data = yaml.safe_load(f) or []
43 # 43 #
44 # if not existing_data: 44 # if not existing_data:
45 # start_id = 1 45 # start_id = 1
46 # else: 46 # else:
47 # start_id = max(item.get('id', 0) for item in existing_data) + 1 47 # start_id = max(item.get('id', 0) for item in existing_data) + 1
48 # 48 #
49 # for i, item in enumerate(data, start=start_id): 49 # for i, item in enumerate(data, start=start_id):
50 # item['id'] = i 50 # item['id'] = i
51 # existing_data.append(item) 51 # existing_data.append(item)
52 # 52 #
53 # with open(file_path, 'w') as f: 53 # with open(file_path, 'w') as f:
54 # yaml.dump(existing_data, f, default_flow_style=False) 54 # yaml.dump(existing_data, f, default_flow_style=False)
55 55
56 def remove_from_yaml_file(file_path, component_name): 56 def remove_from_yaml_file(file_path, component_name):
57 with open(file_path, 'r') as f: 57 with open(file_path, 'r') as f:
58 existing_data = yaml.safe_load(f) or [] 58 existing_data = yaml.safe_load(f) or []
59 59
60 updated_data = [item for item in existing_data if item.get('component_name') != component_name] 60 updated_data = [item for item in existing_data if item.get('component_name') != component_name]
61 61
62 with open(file_path, 'w') as f: 62 with open(file_path, 'w') as f:
63 yaml.dump(updated_data, f, default_flow_style=False) 63 yaml.dump(updated_data, f, default_flow_style=False)
64 64
65 65
66 @components_bp.route('/api/languages', methods=['GET']) 66 @components_bp.route('/api/languages', methods=['GET'])
67 def find_language(): 67 def find_language():
68 components = Component.query.all() 68 components = Component.query.all()
69 languages_paths = [] 69 languages_paths = []
70 # Додаємо головну директорію languages 70 # Додаємо головну директорію languages
71 languages_paths.append('languages') 71 languages_paths.append('languages')
72 # Знаходимо шляхи до директорій languages всередині папки components 72 # Знаходимо шляхи до директорій languages всередині папки components
73 for component in components: 73 for component in components:
74 component_languages_directory = 'components/' + component.name + '/' + component.name + '/languages' 74 component_languages_directory = 'components/' + component.name + '/' + component.name + '/languages'
75 languages_paths.append(component_languages_directory) 75 languages_paths.append(component_languages_directory)
76 result = ';'.join(languages_paths) 76 result = ';'.join(languages_paths)
77 print(result) 77 print(result)
78 return result 78 return result
79 79
80 80
81 @components_bp.route('/', methods=['GET', 'POST']) 81 @components_bp.route('/', methods=['GET', 'POST'])
82 def home(): 82 def home():
83 components = Component.query.all() 83 components = Component.query.all()
84 components_names = [component.name for component in components] 84 components_names = [component.name for component in components]
85 if 'k2site' in components_names: 85 if 'k2site' in components_names:
86 return redirect(url_for('k2test.new_component2')) #змінити на ендпоінт головної k2site 86 return redirect(url_for('k2site.new_component2')) #змінити на ендпоінт головної k2site
87 else: 87 else:
88 return redirect('/dashboard') 88 return redirect('/dashboard')
89 89
90 90
91 91
92 @components_bp.route('/first-login', methods=['GET', 'POST']) 92 @components_bp.route('/first-login', methods=['GET', 'POST'])
93 def first_login(): 93 def first_login():
94 if request.method == "POST": 94 if request.method == "POST":
95 username = request.form.get("username") 95 username = request.form.get("username")
96 password = request.form.get("password") 96 password = request.form.get("password")
97 for user in config["users"]: 97 for user in config["users"]:
98 if user["username"] == username and user["password"] == password: 98 if user["username"] == username and user["password"] == password:
99 session['username'] = username # Збереження ім'я користувача в сесії 99 session['username'] = username # Збереження ім'я користувача в сесії
100 return redirect(url_for('components.dashboard')) 100 return redirect(url_for('components.dashboard'))
101 return "Невірне ім'я користувача або пароль." 101 return "Невірне ім'я користувача або пароль."
102 return render_template('first-login.html') 102 return render_template('first-login.html')
103 103
104 104
105 @components_bp.route('/change_language/<lang>') 105 @components_bp.route('/change_language/<lang>')
106 def change_language(lang): 106 def change_language(lang):
107 session['lang'] = lang 107 session['lang'] = lang
108 k2.current_language = lang 108 k2.current_language = lang
109 return redirect(request.referrer) 109 return redirect(request.referrer)
110 110
111 111
112 @components_bp.route('/dashboard') 112 @components_bp.route('/dashboard')
113 def dashboard(): 113 def dashboard():
114 components = Component.query.all() 114 components = Component.query.all()
115 components_names = []
115 components_names = [component.name for component in components] 116 components_names = [component.name for component in components]
116 if 'k2site' in components_names: 117 if 'k2site' in components_names:
117 return redirect(url_for('components_bp.component_list_dasb')) # змінити на ендпоінт головної k2site 118 return redirect(url_for('components.component_list_dasb')) # змінити на ендпоінт головної k2site
118 else: 119 else:
119 # Компоненти доступні для встановлення 120 # Компоненти доступні для встановлення
120 # GET-запит до API 121 # GET-запит до API
121 try: 122 try:
122 response = requests.get(f'{k2.update_domain}api/components') 123 response = requests.get(f'{k2.update_domain}api/components')
123 json_data = response.json() 124 json_data = response.json()
124 # Перетворення JSON-об'єкту на масив 125 # Перетворення JSON-об'єкту на масив
125 component_server = [item for item in json_data] 126 component_server = [item for item in json_data]
126 except: 127 except:
127 component_server = None 128 component_server = None
128 129
129 # Встановлені компоненти 130 # Встановлені компоненти
130 components = Component.query.all() 131 components = Component.query.all()
131 components_names = [component.name for component in components] 132 components_names = [component.name for component in components]
132 # Отримання значення пошукового запиту з параметрів URL 133 # Отримання значення пошукового запиту з параметрів URL
133 search_query = request.args.get('search_query') 134 search_query = request.args.get('search_query')
134 # print(search_query) 135 # print(search_query)
135 filtered_components = [] 136 filtered_components = []
136 if search_query: 137 if search_query:
137 filtered_components = [component for component in component_server if 138 filtered_components = [component for component in component_server if
138 (search_query.lower() in component['name'].lower() if component['name'] else False) or 139 (search_query.lower() in component['name'].lower() if component['name'] else False) or
139 (search_query.lower() in component['description'].lower() if component[ 140 (search_query.lower() in component['description'].lower() if component[
140 'description'] else False)] 141 'description'] else False)]
141 else: 142 else:
142 filtered_components = component_server 143 filtered_components = component_server
143 current_language = k2.current_language 144 current_language = k2.current_language
144 145
145 return render_template('dashboard.html', components=components, 146 return render_template('dashboard.html', components=components,
146 components_names=components_names, component_server=filtered_components, 147 components_names=components_names, component_server=filtered_components,
147 search_query=search_query, language=current_language) 148 search_query=search_query, language=current_language)
148 149
149 150
150 @components_bp.route('/show_components/<string:component_id>') 151 @components_bp.route('/show_components/<string:component_id>')
151 def show_components(component_id): 152 def show_components(component_id):
152 response = requests.get(f'{k2.update_domain}api/components') 153 response = requests.get(f'{k2.update_domain}api/components')
153 json_data = response.json() 154 json_data = response.json()
154 selected_component = next((component for component in json_data if component['id'] == component_id), None) 155 selected_component = next((component for component in json_data if component['id'] == component_id), None)
155 return render_template('component-info.html', selected_component=selected_component) 156 return render_template('component-info.html', selected_component=selected_component)
156 157
157 158
159 @components_bp.route('/show_components-site/<string:component_id>')
160 def show_components_site(component_id):
161 response = requests.get(f'{k2.update_domain}api/components')
162 json_data = response.json()
163 selected_component = next((component for component in json_data if component['id'] == component_id), None)
164 return render_template('component-info-site.html', selected_component=selected_component)
165
166
158 @components_bp.route('/install_components_git/<string:component_id>') 167 @components_bp.route('/install_components_git/<string:component_id>')
159 def install_components_git(component_id): 168 def install_components_git(component_id):
160 # Шлях до головної папки проекту 169 # Шлях до головної папки проекту
161 project_folder = 'components' 170 project_folder = 'components'
162 # component = Component.get_repository_by_id(component_id) 171 # component = Component.get_repository_by_id(component_id)
163 response = requests.get(f'{k2.update_domain}api/components') 172 response = requests.get(f'{k2.update_domain}api/components')
164 json_data = response.json() 173 json_data = response.json()
165 selected_component = next((component for component in json_data if component['id'] == component_id), None) 174 selected_component = next((component for component in json_data if component['id'] == component_id), None)
166 # Назва репозиторія 175 # Назва репозиторія
167 repository_name = selected_component['name'] 176 repository_name = selected_component['name']
168 # Шлях до папки репозиторія в межах проекту 177 # Шлях до папки репозиторія в межах проекту
169 repository_folder = os.path.join(project_folder, repository_name) 178 repository_folder = os.path.join(project_folder, repository_name)
170 # URL репозиторія 179 # URL репозиторія
171 180
172 git_repo_url = selected_component['git_link'] 181 git_repo_url = selected_component['git_link']
173 try: 182 try:
174 # Перевірка наявності папки репозиторія 183 # Перевірка наявності папки репозиторія
175 if not os.path.exists(repository_folder): 184 if not os.path.exists(repository_folder):
176 # Створення папки репозиторія 185 # Створення папки репозиторія
177 os.makedirs(repository_folder) 186 os.makedirs(repository_folder)
178 # Шлях до файлу __init__.py 187 # Шлях до файлу __init__.py
179 init_file = os.path.join(repository_folder, '__init__.py') 188 init_file = os.path.join(repository_folder, '__init__.py')
180 # Перевірка наявності файлу __init__.py 189 # Перевірка наявності файлу __init__.py
181 if not os.path.exists(init_file): 190 if not os.path.exists(init_file):
182 # Створення пустого файлу __init__.py 191 # Створення пустого файлу __init__.py
183 open(init_file, 'a').close() 192 open(init_file, 'a').close()
184 # підключення до приватного репозиторію 193 # підключення до приватного репозиторію
185 # os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW' 194 # os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW'
186 # git_repo_url_with_token = git_repo_url.replace('https://', 195 # git_repo_url_with_token = git_repo_url.replace('https://',
187 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@') 196 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@')
188 197
189 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія 198 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія
190 command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url, 199 command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url,
191 '--target=' + repository_folder] 200 '--target=' + repository_folder]
192 # Виконуємо команду встановлення 201 # Виконуємо команду встановлення
193 subprocess.check_call(command) 202 subprocess.check_call(command)
194 203
195 # Шлях до файлу, до якого потрібно додати код 204 # Шлях до файлу, до якого потрібно додати код
196 file_path = 'routes.py' 205 file_path = 'routes.py'
197 # Код, який потрібно додати 206 # Код, який потрібно додати
198 code = selected_component['dependencies'] 207 code = selected_component['dependencies']
199 # Відкриття файлу у режимі дозапису 208 # Відкриття файлу у режимі дозапису
200 with open(file_path, 'a') as file: 209 with open(file_path, 'a') as file:
201 # Запис нового коду у файл 210 # Запис нового коду у файл
202 file.write('\n') 211 file.write('\n')
203 file.write(code) 212 file.write(code)
204 file.write('\n') 213 file.write('\n')
205 component = Component.query.filter_by(name=selected_component['name']).first() 214 component = Component.query.filter_by(name=selected_component['name']).first()
206 if not component: 215 if not component:
207 new_component = Component( 216 new_component = Component(
208 name=selected_component['name'], 217 name=selected_component['name'],
209 description=selected_component['description'], 218 description=selected_component['description'],
210 version=selected_component['version'], 219 version=selected_component['version'],
211 git_link=selected_component['git_link'], 220 git_link=selected_component['git_link'],
212 dependencies=selected_component['dependencies'], 221 dependencies=selected_component['dependencies'],
213 installed=True 222 installed=True
214 ) 223 )
215 # Add the new component to the database 224 # Add the new component to the database
216 db.session.add(new_component) 225 db.session.add(new_component)
217 db.session.commit() 226 db.session.commit()
218 227
219 # Повертаємо повідомлення про успішне встановлення 228 # Повертаємо повідомлення про успішне встановлення
220 return f'Installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 229 return f'Installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
221 except subprocess.CalledProcessError as e: 230 except subprocess.CalledProcessError as e:
222 return 'Error installing : ' + str(e) 231 return 'Error installing : ' + str(e)
223 232
224 233
225 @components_bp.route('/install_components/<string:component_id>') 234 @components_bp.route('/install_components/<string:component_id>')
226 def install_component_from_archive(component_id): 235 def install_component_from_archive(component_id):
227 # Шлях до головної папки проекту 236 # Шлях до головної папки проекту
228 project_folder = 'components' 237 project_folder = 'components'
229 # Отримати відповідну компоненту зі списку компонент 238 # Отримати відповідну компоненту зі списку компонент
230 response = requests.get(f'{k2.update_domain}api/components') 239 response = requests.get(f'{k2.update_domain}api/components')
231 json_data = response.json() 240 json_data = response.json()
232 selected_component = next((component for component in json_data if component['id'] == component_id), None) 241 selected_component = next((component for component in json_data if component['id'] == component_id), None)
233 if selected_component is None: 242 if selected_component is None:
234 return 'Component not found' 243 return 'Component not found'
235 # Отримати посилання на архів компоненти та версію 244 # Отримати посилання на архів компоненти та версію
236 archive_url = selected_component['latest_component_data'] 245 archive_url = selected_component['latest_component_data']
237 version = selected_component['latest_version'] 246 version = selected_component['latest_version']
238 try: 247 try:
239 # Створити шлях до папки компоненти згідно назви та версії 248 # Створити шлях до папки компоненти згідно назви та версії
240 component_folder = os.path.join(project_folder) 249 component_folder = os.path.join(project_folder)
241 os.makedirs(component_folder, exist_ok=True) 250 os.makedirs(component_folder, exist_ok=True)
242 # Завантажити архів компоненти 251 # Завантажити архів компоненти
243 response = requests.get(archive_url, stream=True) 252 response = requests.get(archive_url, stream=True)
244 response.raise_for_status() 253 response.raise_for_status()
245 # Шлях до завантаженого архіву 254 # Шлях до завантаженого архіву
246 archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip") 255 archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip")
247 # Зберегти архів на диск 256 # Зберегти архів на диск
248 with open(archive_path, "wb") as file: 257 with open(archive_path, "wb") as file:
249 for chunk in response.iter_content(chunk_size=8192): 258 for chunk in response.iter_content(chunk_size=8192):
250 file.write(chunk) 259 file.write(chunk)
251 # Розпакувати архів 260 # Розпакувати архів
252 with zipfile.ZipFile(archive_path, "r") as zip_ref: 261 with zipfile.ZipFile(archive_path, "r") as zip_ref:
253 zip_ref.extractall(component_folder) 262 zip_ref.extractall(component_folder)
254 # Видалити архів 263 # Видалити архів
255 os.remove(archive_path) 264 os.remove(archive_path)
256 #перейменувати якщо git 265 #перейменувати якщо git
257 component_name = selected_component['name'] 266 component_name = selected_component['name']
258 old_folder_path = os.path.join(component_folder, component_name + ".git") 267 old_folder_path = os.path.join(component_folder, component_name + ".git")
259 new_folder_path = os.path.join(component_folder, component_name) 268 new_folder_path = os.path.join(component_folder, component_name)
260 # Перевірка наявності папки зі старою назвою 269 # Перевірка наявності папки зі старою назвою
261 if os.path.exists(old_folder_path) and os.path.isdir(old_folder_path): 270 if os.path.exists(old_folder_path) and os.path.isdir(old_folder_path):
262 # Перейменування папки зі старою назвою на нову назву 271 # Перейменування папки зі старою назвою на нову назву
263 os.rename(old_folder_path, new_folder_path) 272 os.rename(old_folder_path, new_folder_path)
264 273
265 # Шлях до файлу, до якого потрібно додати роути 274 # Шлях до файлу, до якого потрібно додати роути
266 file_path = 'routes.py' 275 file_path = 'routes.py'
267 # Код, який потрібно додати 276 # Код, який потрібно додати
268 code = f'''from components.{selected_component['name']}.{selected_component['name']}.views import {selected_component['name']}\napp.register_blueprint({selected_component['name']}, url_prefix='/{selected_component['name']}')''' 277 if component_name == 'k2grid_base':
269 # selected_component['dependencies'] 278 code = f'''from components.{selected_component['name']}.{selected_component['name']}.views import {selected_component['name']}\napp.register_blueprint({selected_component['name']}, url_prefix='/')'''
279 elif component_name == 'k2site':
280 code = f'''from components.{selected_component['name']}.{selected_component['name']}.views import {selected_component['name']}\napp.register_blueprint({selected_component['name']}, url_prefix='/{selected_component['name']}')\nlogin_manager = k2().init_lm(app)'''
281 else:
282 code = f'''from components.{selected_component['name']}.{selected_component['name']}.views import {selected_component['name']}\napp.register_blueprint({selected_component['name']}, url_prefix='/{selected_component['name']}')'''
270 283
284
285
271 # Відкриття файлу у режимі дозапису 286 # Відкриття файлу у режимі дозапису
272 with open(file_path, 'a') as file: 287 with open(file_path, 'a') as file:
273 # Запис нового коду у файл 288 # Запис нового коду у файл
274 file.write('\n') 289 file.write('\n')
275 file.write(code) 290 file.write(code)
276 file.write('\n') 291 file.write('\n')
277 292
278 # Update database with the installed component 293 # Update database with the installed component
279 component = Component.query.filter_by(name=selected_component['name']).first() 294 component = Component.query.filter_by(name=selected_component['name']).first()
280 if not component: 295 if not component:
281 component = Component( 296 component = Component(
282 name=selected_component['name'], 297 name=selected_component['name'],
283 description=selected_component['description'], 298 description=selected_component['description'],
284 version=version, 299 version=version,
285 git_link=selected_component['git_link'], 300 git_link=selected_component['git_link'],
286 dependencies=code, 301 dependencies=code,
287 installed=True 302 installed=True
288 ) 303 )
289 db.session.add(component) 304 db.session.add(component)
290 else: 305 else:
291 component.version = version 306 component.version = version
292 component.git_link = selected_component['git_link'] 307 component.git_link = selected_component['git_link']
293 component.dependencies = code 308 component.dependencies = code
294 component.installed = True 309 component.installed = True
295 310
296 db.session.commit() 311 db.session.commit()
297 312
298 # add language folders 313 # add language folders
299 k2.search_babel_translation_directories() 314 k2.search_babel_translation_directories()
300 return f'''Component installed successfully: {selected_component["name"]} v{version} {k2.babel_translation_directories}, 315 return f'''Component installed successfully: {selected_component["name"]} v{version} {k2.babel_translation_directories},
301 \n \n please wait installing requirments... 316 \n \n please wait installing requirments...
302 <meta http-equiv="refresh" content="0;url=/install-requirments/{selected_component["name"]}" />''' 317 <meta http-equiv="refresh" content="0;url=/install-requirments/{selected_component["name"]}" />'''
303 318
304 except Exception as e: 319 except Exception as e:
305 return f'Error installing component: {str(e)}' 320 return f'Error installing component: {str(e)}'
306 321
307 322
308 @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET']) 323 @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET'])
309 def install_requirments(selected_component_name): 324 def install_requirments(selected_component_name):
310 # menu items 325 # menu items
311 get_admin_menu() 326 get_admin_menu()
312 327
313 328
314 # install requirements 329 ## install requirements for windows
330 #venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/Scripts')
331 #requirements_file = os.path.join('components', selected_component_name, "requirements.txt")
332 #if os.path.isfile(requirements_file):
333 # pip_command = f"{venv_bin_path}/python -m pip install -r {requirements_file}"
334 # subprocess.run(pip_command, shell=True, check=True)
335
336 #install requirements for linux
337 venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/bin')
315 requirements_file = os.path.join('components', selected_component_name, "requirements.txt") 338 requirements_file = os.path.join('components', selected_component_name, "requirements.txt")
316 if os.path.isfile(requirements_file): 339 if os.path.isfile(requirements_file):
317 pip_command = f"{k2.venv_bin_path}/python -m pip install -r {requirements_file}" 340 pip_command = f"{venv_bin_path}/python3 -m pip install -r {requirements_file}"
318 subprocess.run(pip_command, shell=True, check=True) 341 subprocess.run(pip_command, shell=True, check=True)
342
319 return f'''Requirements installed successfully 343 return f'''Requirements installed successfully
320 \n \n please wait installing requirments components... 344 \n \n please wait installing requirments components...
321 <meta http-equiv="refresh" content="1;url=/install-requirments-components" />''' 345 <meta http-equiv="refresh" content="1;url=/install-requirments-components" />'''
322 346
323 347
324 @components_bp.route('/install-requirments-components') 348 @components_bp.route('/install-requirments-components')
325 def install_requirements_components(): 349 def install_requirements_components():
326 # Откриття файлу requirements_components.txt 350 # Откриття файлу requirements_components.txt
327 requirements_file = 'requirements_components.txt' 351 requirements_file = 'requirements_components.txt'
328 component_ids = None 352 component_ids = None
329 if os.path.isfile(requirements_file): 353 if os.path.isfile(requirements_file):
330 with open('requirements_components.txt', 'r') as file: 354 with open('requirements_components.txt', 'r') as file:
331 component_ids = file.read().splitlines() 355 component_ids = file.read().splitlines()
332 if component_ids: 356 if component_ids:
333 for component_id in component_ids: 357 for component_id in component_ids:
334 # Виклик роуту '/install_components/<string:component_name>' для кожної назви компоненти 358 # Виклик роуту '/install_components/<string:component_name>' для кожної назви компоненти
335 response = requests.get( 359 response = requests.get(
336 f'/install_components/{component_id}') 360 f'/install_components/{component_id}')
337 return f'Requirements components installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 361 return f'Requirements components installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
338 else: 362 else:
339 return f'<meta http-equiv="refresh" content="1;url=/dashboard" />' 363 return f'<meta http-equiv="refresh" content="1;url=/dashboard" />'
340 # Опрацювання відповіді (за потреби) 364 # Опрацювання відповіді (за потреби)
341 365
342 366
343 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET']) 367 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET'])
344 def remove_dependencies(component_id): 368 def remove_dependencies(component_id):
345 # Знаходимо компоненту за її ID 369 # Знаходимо компоненту за її ID
346 component = Component.query.get(component_id) 370 component = Component.query.get(component_id)
347 if not component: 371 if not component:
348 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />' 372 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />'
349 # remove menu items 373 # remove menu items
350 component_name = component.name 374 component_name = component.name
351 # file_path = "components/menu.yml" 375 # file_path = "components/menu.yml"
352 # remove_from_yaml_file(file_path, component_name) 376 # remove_from_yaml_file(file_path, component_name)
353 requests.get(f"{k2.domain}api/add-to-menu") 377 requests.get(f"{k2.domain}api/add-to-menu")
354 # remove routes 378 # remove routes
355 file_path = 'routes.py' 379 file_path = 'routes.py'
356 with open(file_path, 'r') as file: 380 with open(file_path, 'r') as file:
357 lines = file.readlines() 381 lines = file.readlines()
358 382
359 updated_lines = [line for line in lines if line.strip() not in component.dependencies] 383 updated_lines = [line for line in lines if line.strip() not in component.dependencies]
360 with open(file_path, 'w') as file: 384 with open(file_path, 'w') as file:
361 file.writelines(updated_lines) 385 file.writelines(updated_lines)
362 386
363 component.installed = False 387 component.installed = False
364 db.session.commit() 388 db.session.commit()
365 389 response = requests.get(f"{k2.domain}/k2site/new_component2")
366 return 'Component successfully turn off <meta http-equiv="refresh" content="1;url=/dashboard" />' 390 return 'Component successfully turn off <meta http-equiv="refresh" content="1;url=/dashboard" />'
367 391
368 392
369 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET']) 393 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET'])
370 def add_dependencies(component_id): 394 def add_dependencies(component_id):
371 # Знаходимо компоненту за її ID 395 # Знаходимо компоненту за її ID
372 component = Component.query.get(component_id) 396 component = Component.query.get(component_id)
373 if not component: 397 if not component:
374 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />' 398 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />'
375 399
376 file_path = 'routes.py' 400 file_path = 'routes.py'
377 code = component.dependencies 401 code = component.dependencies
378 # Відкриття файлу у режимі дозапису 402 # Відкриття файлу у режимі дозапису
379 with open(file_path, 'a') as file: 403 with open(file_path, 'a') as file:
380 # Запис нового коду у файл 404 # Запис нового коду у файл
381 file.write(code) 405 file.write(code)
382 406
383 # Оновлюємо статус компоненти 407 # Оновлюємо статус компоненти
384 component.installed = True 408 component.installed = True
385 db.session.commit() 409 db.session.commit()
386 return 'Dependencies added successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 410 response = requests.get(f"{k2.domain}/k2site/new_component2")
411 return 'Dependencies added successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
387 412
388 413
389 @components_bp.route('/remove-component/<string:component_id>') 414 @components_bp.route('/remove-component/<string:component_id>')
390 def remove_component(component_id): 415 def remove_component(component_id):
391 # Шлях до головної папки проекту 416 # Шлях до головної папки проекту
392 project_folder = 'components' 417 project_folder = 'components'
393 component = Component.query.get(component_id) 418 component = Component.query.get(component_id)
394 # Назва репозиторія 419 # Назва репозиторія
395 repository_name = component.name 420 repository_name = component.name
396 # Шлях до папки репозиторія в межах проекту 421 # Шлях до папки репозиторія в межах проекту
397 repository_folder = os.path.join(project_folder, repository_name) 422 repository_folder = os.path.join(project_folder, repository_name)
398 try: 423 try:
399 # Перевірка наявності папки репозиторія 424 # Перевірка наявності папки репозиторія
400 if os.path.exists(repository_folder): 425 if os.path.exists(repository_folder):
401 # Видалення папки репозиторія 426 # Видалення папки репозиторія
402 shutil.rmtree(repository_folder) 427 shutil.rmtree(repository_folder)
403 # Видаляємо компоненту з бази 428 # Видаляємо компоненту з бази
404 if component: 429 if component:
405 db.session.delete(component) 430 db.session.delete(component)
406 db.session.commit() 431 db.session.commit()
407 432
408 # Повертаємо повідомлення про успішне видалення 433 # Повертаємо повідомлення про успішне видалення
409 return 'Component removed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 434 return 'Component removed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
410 except Exception as e: 435 except Exception as e:
411 # Повертаємо повідомлення про помилку видалення 436 # Повертаємо повідомлення про помилку видалення
412 return 'Error removing component: ' + str(e) 437 return 'Error removing component: ' + str(e)
438 response = requests.get(f"{k2.domain}/k2site/new_component2")
413 439
414 440
415 # @components_bp.route('/component/add') 441 # @components_bp.route('/component/add')
416 # def component_add(): 442 # def component_add():
417 # # components for install 443 # # components for install
418 # try: 444 # try:
419 # # GET-requests to API 445 # # GET-requests to API
420 # response = requests.get(f'{k2.update_domain}api/components') 446 # response = requests.get(f'{k2.update_domain}api/components')
421 # json_data = response.json() 447 # json_data = response.json()
422 # for item in json_data: 448 # for item in json_data:
423 # item['button'] = f"{k2.domain}/install_components/{item['id']}" 449 # item['button'] = f"{k2.domain}/install_components/{item['id']}"
424 # 450 #
425 # except: 451 # except:
426 # json_data = None 452 # json_data = None
427 # return jsonify(json_data) 453 # return jsonify(json_data)
428 # 454 #
429 # 455 #
430 # @components_bp.route('/component/list') 456 # @components_bp.route('/component/list')
431 # def component_list(): 457 # def component_list():
432 # # Встановлені компоненти 458 # # Встановлені компоненти
433 # component_list = [] 459 # component_list = []
434 # components = Component.query.all() 460 # components = Component.query.all()
435 # for component in components: 461 # for component in components:
436 # component_dict = {} 462 # component_dict = {}
437 # component_dict['name'] = component.name 463 # component_dict['name'] = component.name
438 # component_dict['id'] = component.id 464 # component_dict['id'] = component.id
439 # component_dict['description'] = component.description 465 # component_dict['description'] = component.description
440 # component_dict['version'] = component.version 466 # component_dict['version'] = component.version
441 # component_dict['button_off'] =f"{k2.domain}/remove_dependencies/{component.id}" 467 # component_dict['button_off'] =f"{k2.domain}/remove_dependencies/{component.id}"
442 # component_dict['button_on'] = f"{k2.domain}/add_dependencies/{component.id}" 468 # component_dict['button_on'] = f"{k2.domain}/add_dependencies/{component.id}"
443 # component_dict['button_del'] = f"{k2.domain}/remove-component/{component.id}" 469 # component_dict['button_del'] = f"{k2.domain}/remove-component/{component.id}"
444 # component_list.append(component_dict) 470 # component_list.append(component_dict)
445 # return jsonify(component_list) 471 # return jsonify(component_list)
446 472
447 473
448 # menu 474 # menu
449 @components_bp.route('/api/add-to-menu', methods=['GET']) 475 @components_bp.route('/api/add-to-menu', methods=['GET'])
450 def add_to_menu(): 476 def add_to_menu():
451 data = [] 477 data = []
452 response = requests.get(f"{k2.domain}/menu-admin-items") 478 response = requests.get(f"{k2.domain}/menu-admin-items")
453 data.append(response.json()[0]) 479 data.append(response.json()[0])
454 prev_menu = response.json()[0]['title'] 480 prev_menu = response.json()[0]['title']
455 for item in response.json()[0]['children']: 481 for item in response.json()[0]['children']:
456 name_menu = str(item['to']).replace('/','-') 482 name_menu = 'k2itm'+ item['to'].replace('/','-')
457 caption_menu = item['title'] 483 caption_menu = item['title']
458 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu) 484 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu)
459 components = Component.query.all() 485 components = Component.query.all()
460 components_names = [component.name for component in components] 486 components_names = [component.name for component in components]
461 for components_names in components_names: 487 for components_names in components_names:
462 response = requests.get(f"{k2.domain}{components_names}/menu-admin-items") 488 response = requests.get(f"{k2.domain}{components_names}/menu-admin-items")
463 if response.status_code == 200: 489 if response.status_code == 200:
464 data.append(response.json()[0]) 490 data.append(response.json()[0])
465 #prev_menu = 491 #prev_menu =
466 prev_menu = response.json()[0]['title'] 492 prev_menu = response.json()[0]['title']
467 for item in response.json()[0]['children']: 493 for item in response.json()[0]['children']:
468 name_menu = item['to'] 494 name_menu = 'k2itm'+ item['to'].replace('/','-')
469 caption_menu = item['title'] 495 caption_menu = item['title']
470 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu) 496 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu)
471 else: 497 else:
472 data 498 continue
473 # add component_name key for menu items 499 # add component_name key for menu items
474 for item in data: 500 #for item in data:
475 item['component_name'] = components_names 501 # item['component_name'] = components_names
476 k2.menu = data 502 #k2.menu = data
477 return k2.menu 503 return data
478 504
479 505
506
507
480 @components_bp.route('/api/main-menu/') 508 @components_bp.route('/api/main-menu/')
481 @jwt_required() 509 @login_required
482 def get_admin_menu(): 510 def get_admin_menu():
483 current_user = get_jwt_identity() 511 components = Component.query.all()
484 role_id = current_user['user_role'] 512 components_names = [component.name for component in components]
513 if 'k2site' in components_names:
514 role_id = current_user.get_role_id()
485 filter_menu = [] 515 filter_menu = []
486 response = requests.get(f"{k2.domain}api/add-to-menu") 516 response = requests.get(f"{k2.domain}api/add-to-menu")
487 menu_items_list = K2admin_menus.get_menu_items_by_roles(role_id) 517 menu_items_list = K2admin_menus.get_menu_items_by_roles(role_id)
488 518 #print(menu_items_list)
489 for item in response.json(): 519 for item in response.json():
490 filtered_children = [] 520 filtered_children = []
491 for im in item['children']: 521 for im in item['children']:
492 522 if 'k2itm' + im['to'].replace('/','-') in menu_items_list:
493 if im['to'] in menu_items_list:
494 filtered_children.append(im) 523 filtered_children.append(im)
495 if filtered_children: 524 if filtered_children:
496 item['children'] = filtered_children 525 item['children'] = filtered_children
497 filter_menu.append(item) 526 filter_menu.append(item)
498 filter_menu.append({"heading": 'APPS & PAGES'}) 527 # filter_menu.append({"heading": 'APPS & PAGES'})
499
500 return jsonify(filter_menu) 528 return jsonify(filter_menu)
501 529
502 530
503 def add_menu_with_permissions_db(name_menu, prev_menu, caption_menu): 531 def add_menu_with_permissions_db(name_menu, prev_menu, caption_menu):
504 532
505 # Створення об'єкта k2admin_menus 533 # Створення об'єкта k2admin_menus
506 menu = text('SELECT COUNT(*) FROM k2admin_menus WHERE namemenu = :name_menu') 534 menu = text('SELECT COUNT(*) FROM k2admin_menus WHERE namemenu = :name_menu')
507 result = db.session.execute(menu, {'name_menu': name_menu}).fetchone() 535 result = db.session.execute(menu, {'name_menu': name_menu}).fetchone()
508 count = result[0] 536 count = result[0]
509 if count == 0: 537 if count == 0:
510 new_menu_element = K2admin_menus( 538 new_menu_element = K2admin_menus(
511 namemenu=name_menu, 539 namemenu=name_menu,
512 prevmenu=prev_menu, 540 prevmenu=prev_menu,
513 caption=caption_menu, 541 caption=caption_menu,
514 module_name=name_menu 542 module_name=name_menu
515 ) 543 )
516 db.session.add(new_menu_element) 544 db.session.add(new_menu_element)
517 db.session.commit() 545 db.session.commit()
518 # Створення об'єкта k2admin_menus_prava 546 # Створення об'єкта k2admin_menus_prava
519 new_prava = K2admin_Menus_Prava( 547 new_prava = K2admin_Menus_Prava(
520 menuid=new_menu_element.menuid, # Зв'язуємо зовнішній ключ з menuid нового меню 548 menuid=new_menu_element.menuid, # Зв'язуємо зовнішній ключ з menuid нового меню
521 username=None, 549 username=None,
522 r=0, 550 r=0,
523 w=0, 551 w=0,
524 i=0, 552 i=0,
525 d=0, 553 d=0,
526 c=0, 554 c=0,
527 exp=0, 555 exp=0,
528 imp=0, 556 imp=0,
529 settable=0, 557 settable=0,
530 cutpast=0, 558 cutpast=0,
531 enable=0, 559 enable=0,
532 roleid=-1 560 roleid=-1
533 ) 561 )
534 # Додавання об'єкта k2admin_menus_prava до сесії 562 # Додавання об'єкта k2admin_menus_prava до сесії
535 db.session.add(new_prava) 563 db.session.add(new_prava)
536 db.session.commit() 564 db.session.commit()
537 565
538 @components_bp.route('/component-add') 566 @components_bp.route('/component-add')
567 @login_required
539 def component_add_dasb(): 568 def component_add_dasb():
540 try: 569 try:
541 response = requests.get(f'{k2.update_domain}api/components') 570 response = requests.get(f'{k2.update_domain}api/components')
542 json_data = response.json() 571 json_data = response.json()
543 # Перетворення JSON-об'єкту на масив 572 # Перетворення JSON-об'єкту на масив
544 component_server = [item for item in json_data] 573 component_server = [item for item in json_data]
545 except: 574 except:
546 component_server = None 575 component_server = None
547 # Отримання значення пошукового запиту з параметрів URL 576 # Отримання значення пошукового запиту з параметрів URL
548 search_query = request.args.get('search_query') 577 search_query = request.args.get('search_query')
549 # print(search_query) 578 # print(search_query)
550 filtered_components = [] 579 filtered_components = []
551 if search_query: 580 if search_query:
552 filtered_components = [component for component in component_server if 581 filtered_components = [component for component in component_server if
553 (search_query.lower() in component['name'].lower() if component[ 582 (search_query.lower() in component['name'].lower() if component[
554 'name'] else False) or 583 'name'] else False) or
555 (search_query.lower() in component['description'].lower() if component[ 584 (search_query.lower() in component['description'].lower() if component[
556 'description'] else False)] 585 'description'] else False)]
557 else: 586 else:
558 filtered_components = component_server 587 filtered_components = component_server
588 components = Component.query.all()
589 components_names = [component.name for component in components]
559 590
560 return render_template('dashboard-add.html', 591 return render_template('dashboard-add.html',
561 component_server=filtered_components, 592 component_server=filtered_components, search_query=search_query, components_names=components_names )
562 )
563 593
594
595
564 @components_bp.route('/component-list') 596 @components_bp.route('/component-list')
597 @login_required
565 def component_list_dasb(): 598 def component_list_dasb():
566 components = Component.query.all() 599 components = Component.query.all()
600
567 return render_template('dashboard-list.html', components=components) 601 return render_template('dashboard-list.html', components=components)
568 602
569 603
570 604
605
571 @components_bp.route('/menu-admin-items') 606 @components_bp.route('/menu-admin-items')
572 def menu_items(): 607 def menu_items():
573 menu = [ 608 menu = [
574 { 609 {
575 "title": 'Add components', 610 "title": 'Add components',
576 "icon": {"icon": 'mdi-account-circle-outline'}, 611 "icon": {"icon": 'mdi-account-circle-outline'},
577 "children": [ 612 "children": [
578 {'title': 'Install components', 'to': 'component-add'}, 613 {'title': 'Install new components', 'to': '/component-add'},
579 {'title': 'Installed components', 'to': 'component-list'}, 614 {'title': 'Installed components', 'to': '/component-list'},
580 615
581 ], 616 ],
582 }] 617 }]
583 return menu 618 return menu
584 619
585 620
586 621
587 622
languages/babel_translation_directories.yml
1 babel_translation_directories: languages;components/k2test/k2test/languages;components/k2auth/k2auth/languages;components/k2adm/k2adm/languages 1 babel_translation_directories: languages;components/k2site/k2site/languages;components/k2adm/k2adm/languages;components/k2test/k2test/languages;components/k2grid_base/k2grid_base/languages
2 2
languages/en/LC_MESSAGES/messages.mo
No preview for this file type
languages/en/LC_MESSAGES/messages.po
1 msgid "t_installed_components" 1 msgid "t_installed_components"
2 msgstr "Installed components" 2 msgstr "Installed components"
3 3
4 msgid "t_name" 4 msgid "t_name"
5 msgstr "Name" 5 msgstr "Name"
6 6
7 msgid "t_description" 7 msgid "t_description"
8 msgstr "Description" 8 msgstr "Description"
9 9
10 msgid "t_version" 10 msgid "t_version"
11 msgstr "Version" 11 msgstr "Version"
12 12
13 msgid "t_dependencies" 13 msgid "t_dependencies"
14 msgstr "Dependencies" 14 msgstr "Dependencies"
15 15
16 msgid "t_git_link" 16 msgid "t_git_link"
17 msgstr "Git Link" 17 msgstr "Git Link"
18 18
19 msgid "t_install_at" 19 msgid "t_install_at"
20 msgstr "Install At" 20 msgstr "Install At"
21 21
22 msgid "t_status" 22 msgid "t_status"
23 msgstr "Status" 23 msgstr "Status"
24 24
25 msgid "t_action" 25 msgid "t_action"
26 msgstr "Action" 26 msgstr "Action"
27 27
28 msgid "t_components_shop" 28 msgid "t_components_shop"
29 msgstr "Add component" 29 msgstr "Add component"
30
31 msgid "t_components_delete"
32 msgstr "Delete component"
33
34 msgid "t_close_popup"
35 msgstr "Close"
36
37 msgid "t_delete_popup"
38 msgstr "Delete"
39
40 msgid "t_turn_of_component"
41 msgstr "Turn off component"
42
43 msgid "t_turn_on_component"
44 msgstr "Turn on component"
languages/pl/LC_MESSAGES/messages.mo
No preview for this file type
languages/pl/LC_MESSAGES/messages.po
1 msgid "" 1 msgid ""
2 msgstr "" 2 msgstr ""
3 "Content-Type: text/plain; charset=UTF-8\n" 3 "Content-Type: text/plain; charset=UTF-8\n"
4 "Content-Transfer-Encoding: 8bit\n" 4 "Content-Transfer-Encoding: 8bit\n"
5 5
6 msgid "t_installed_components" 6 msgid "t_installed_components"
7 msgstr "Zainstalowane komponenty" 7 msgstr "Zainstalowane komponenty"
8 8
9 msgid "t_name" 9 msgid "t_name"
10 msgstr "Nazwa" 10 msgstr "Nazwa"
11 11
12 msgid "t_description" 12 msgid "t_description"
13 msgstr "Opis" 13 msgstr "Opis"
14 14
15 msgid "t_version" 15 msgid "t_version"
16 msgstr "Wersja" 16 msgstr "Wersja"
17 17
18 msgid "t_dependencies" 18 msgid "t_dependencies"
19 msgstr "Zależności" 19 msgstr "Zależności"
20 20
21 msgid "t_git_link" 21 msgid "t_git_link"
22 msgstr "Link do Git" 22 msgstr "Link do Git"
23 23
24 msgid "t_install_at" 24 msgid "t_install_at"
25 msgstr "Zainstalowano" 25 msgstr "Zainstalowano"
26 26
27 msgid "t_status" 27 msgid "t_status"
28 msgstr "Status" 28 msgstr "Status"
29 29
30 msgid "t_action" 30 msgid "t_action"
31 msgstr "Akcja" 31 msgstr "Akcja"
32 32
33 msgid "t_components_shop" 33 msgid "t_components_shop"
34 msgstr "Dodaj komponent" 34 msgstr "Dodaj komponent"
35
36 msgid "t_components_delete"
37 msgstr "Usuń komponent"
38
39 msgid "t_close_popup"
40 msgstr "Zamknij"
41
42 msgid "t_delete_popup"
43 msgstr "Usuń"
44
45 msgid "t_turn_of_component"
46 msgstr "Wyłącz komponent"
47
48 msgid "t_turn_on_component"
49 msgstr "Włącz komponent"
languages/uk/LC_MESSAGES/messages.mo
No preview for this file type
languages/uk/LC_MESSAGES/messages.po
1 msgid "" 1 msgid ""
2 msgstr "" 2 msgstr ""
3 "Content-Type: text/plain; charset=UTF-8\n" 3 "Content-Type: text/plain; charset=UTF-8\n"
4 "Content-Transfer-Encoding: 8bit\n" 4 "Content-Transfer-Encoding: 8bit\n"
5 5
6 msgid "t_installed_components" 6 msgid "t_installed_components"
7 msgstr "Встановлені компоненти" 7 msgstr "Встановлені компоненти"
8 8
9 msgid "t_name" 9 msgid "t_name"
10 msgstr "Назва" 10 msgstr "Назва"
11 11
12 msgid "t_description" 12 msgid "t_description"
13 msgstr "Опис" 13 msgstr "Опис"
14 14
15 msgid "t_version" 15 msgid "t_version"
16 msgstr "Версія" 16 msgstr "Версія"
17 17
18 msgid "t_dependencies" 18 msgid "t_dependencies"
19 msgstr "Залежності" 19 msgstr "Залежності"
20 20
21 msgid "t_git_link" 21 msgid "t_git_link"
22 msgstr "Посилання на Git" 22 msgstr "Посилання на Git"
23 23
24 msgid "t_install_at" 24 msgid "t_install_at"
25 msgstr "Встановлено" 25 msgstr "Встановлено"
26 26
27 msgid "t_status" 27 msgid "t_status"
28 msgstr "Статус" 28 msgstr "Статус"
29 29
30 msgid "t_action" 30 msgid "t_action"
31 msgstr "Дія" 31 msgstr "Дія"
32 32
33 msgid "t_components_shop" 33 msgid "t_components_shop"
34 msgstr "Додати компоненту" 34 msgstr "Додати компоненту"
35
36 msgid "t_components_delete"
37 msgstr "Видалити компоненту"
38
39 msgid "t_close_popup"
40 msgstr "Закрити"
41
42 msgid "t_delete_popup"
43 msgstr "Видалити"
44
45 msgid "t_turn_of_component
46 msgstr "Вимкнути"
47
48 msgid "t_turn_on_component"
49 msgstr "Увімкнути"
1 #app = Flask(__name__) 1 #app = Flask(__name__)
2 from app import app 2 from app import app
3 from k2.k2rout import components_bp 3 from k2.k2rout import components_bp
4 from k2.k2cfg import k2
4 app.register_blueprint(components_bp) 5 app.register_blueprint(components_bp)
5 from components.k2test.k2test.views import k2test 6 #k2grid_base
6 app.register_blueprint(k2test, url_prefix='/k2test')
templates/base.html
1 <!DOCTYPE html> File was deleted
2 <html>
3 <head>
4 <title>{% block title %}{% endblock %}</title>
5 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
6 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
7 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
8 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
9 <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
10
11
12
13 {% block styles %}
14 <!-- Підключення CSS-стилів -->
15 {% endblock %}
16 </head>
17 <body>
18 ########################
19 <div class="content">
20 {% block content %}dashboard{% endblock %}
21 </div>
22 <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
23 <footer>
24 &copy; 2023 Корпорація k2
25 </footer>
26
27
28 {% block scripts %}
29 <!-- Підключення скриптів JavaScript -->
30 {% endblock %}
31 </body>
32 </html>
templates/component-info-site.html
File was created 1 {% extends 'base.html' %}
2 {% block styles %}
3 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
4
5 <style>
6 .bd-placeholder-img {
7 font-size: 1.125rem;
8 text-anchor: top;
9 -webkit-user-select: none;
10 -moz-user-select: none;
11 user-select: none;
12 }
13
14 @media (min-width: 768px) {
15 .bd-placeholder-img-lg {
16 font-size: 3.5rem;
17 }
18 }
19
20 .b-example-divider {
21 height: 3rem;
22 background-color: rgba(0, 0, 0, .1);
23 border: solid rgba(0, 0, 0, .15);
24 border-width: 1px 0;
25 box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
26 }
27
28 @media (min-width: 992px) {
29 .rounded-lg-3 { border-radius: .3rem; }
30 }
31 </style>
32
33
34 {% endblock %}
35 {% block content %}
36 <div id="popupBackdrop">
37 <div class="loader">
38 Встановлення компоненти... <i class="fa-solid fa-cog fa-spin fa-xl"></i>
39 </div>
40 </div>
41
42 {% if selected_component %}
43 <div class="text-center border-bottom">
44 <img class="d-block mx-auto mb-4" src="{{ url_for('static', filename='img/logo-k2.png')}}" alt="" width="200">
45 <h3 class="display-4 fw-bold">K2CloudERP-2.5.1.27</h3>
46 <h1 class="display-4 fw-bold">{{selected_component.name|title}}</h1>
47 <div class="col-lg-6 mx-auto">
48 <p class="lead mb-4">{{selected_component.description|title}} -
49 quickly design and customize responsive mobile-first components with Python and Bootstrap.
50 </p>
51 <p class="lead mb-4">Посилання на репозиторій: {{selected_component.git_link}}</p>
52 <p class="lead mb-4">Версія: {{selected_component.version}}</p>
53 <p class="lead mb-4">Розробка: K2 Cloud</p>
54 <div class="d-grid gap-2 d-sm-flex justify-content-sm-center mb-5">
55
56 <a href="/install_components/{{ selected_component.id }}" id="installBtn" class="btn btn-primary btn-lg px-4 me-sm-3" onclick="showLoader()">Встановити компоненту</a>
57 </div>
58 </div>
59 <div class="overflow-hidden" style="max-height: 30vh;">
60 <div class="container px-5">
61 <img src="https://corp2.eu/media/assets/images/service/k2cloud.jpg" class="img-fluid border rounded-3 shadow-lg mb-4" alt="Example image" width="700" height="500" loading="lazy">
62 </div>
63 </div>
64 </div>
65
66 {% else %}
67 Помилка завантаження компоненти з сервера
68 {% endif %}
69
70 <script>
71 function showLoader() {
72 document.getElementById("popupBackdrop").style.display = "block";
73 }
74
75 function hideLoader() {
76 document.getElementById("popupBackdrop").style.display = "none";
77 }
78
79 window.onload = function() {
80 hideLoader();
81 };
82 </script>
83
84
85 {% endblock %}
86
87
templates/component-info.html
1 {% if 'base.html' in template_list %}
2 {% extends 'base.html' %}
3 {% else %}
4
5 {% endif %}
6
7 {% block styles %} 1 {% block styles %}
8 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> 2 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
9
10 <style> 3 <style>
11 .bd-placeholder-img { 4 .bd-placeholder-img {
12 font-size: 1.125rem; 5 font-size: 1.125rem;
13 text-anchor: top; 6 text-anchor: top;
14 -webkit-user-select: none; 7 -webkit-user-select: none;
15 -moz-user-select: none; 8 -moz-user-select: none;
16 user-select: none; 9 user-select: none;
17 } 10 }
18 11
19 @media (min-width: 768px) { 12 @media (min-width: 768px) {
20 .bd-placeholder-img-lg { 13 .bd-placeholder-img-lg {
21 font-size: 3.5rem; 14 font-size: 3.5rem;
22 } 15 }
23 } 16 }
24 17
25 .b-example-divider { 18 .b-example-divider {
26 height: 3rem; 19 height: 3rem;
27 background-color: rgba(0, 0, 0, .1); 20 background-color: rgba(0, 0, 0, .1);
28 border: solid rgba(0, 0, 0, .15); 21 border: solid rgba(0, 0, 0, .15);
29 border-width: 1px 0; 22 border-width: 1px 0;
30 box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15); 23 box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
31 } 24 }
32 25
33 @media (min-width: 992px) { 26 @media (min-width: 992px) {
34 .rounded-lg-3 { border-radius: .3rem; } 27 .rounded-lg-3 { border-radius: .3rem; }
35 } 28 }
36 </style> 29 </style>
30 {% endblock %}
31 <!DOCTYPE html>
32 <html>
33 <head>
34 <title>{% block title %}{% endblock %}</title>
35 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
36 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
37 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
38 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
39 <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
37 40
38 41
39 {% endblock %} 42 </head>
43 <body>
44
45
40 {% block content %} 46 {% block content %}
41 <div id="popupBackdrop"> 47 <div id="popupBackdrop">
42 <div class="loader"> 48 <div class="loader">
43 Встановлення компоненти... <i class="fa-solid fa-cog fa-spin fa-xl"></i> 49 Встановлення компоненти... <i class="fa-solid fa-cog fa-spin fa-xl"></i>
44 </div> 50 </div>
45 </div> 51 </div>
46 52
47 {% if selected_component %} 53 {% if selected_component %}
48 <div class="text-center border-bottom"> 54 <div class="text-center border-bottom">
49 <img class="d-block mx-auto mb-4" src="{{ url_for('static', filename='img/logo-k2.png')}}" alt="" width="200"> 55 <img class="d-block mx-auto mb-4" src="{{ url_for('static', filename='img/logo-k2.png')}}" alt="" width="200">
50 <h3 class="display-4 fw-bold">K2CloudERP-2.5.1.27</h3> 56 <h3 class="display-4 fw-bold">K2CloudERP-2.5.1.27</h3>
51 <h1 class="display-4 fw-bold">{{selected_component.name|title}}</h1> 57 <h1 class="display-4 fw-bold">{{selected_component.name|title}}</h1>
52 <div class="col-lg-6 mx-auto"> 58 <div class="col-lg-6 mx-auto">
53 <p class="lead mb-4">{{selected_component.description|title}} - 59 <p class="lead mb-4">{{selected_component.description|title}} -
54 quickly design and customize responsive mobile-first components with Python and Bootstrap. 60 quickly design and customize responsive mobile-first components with Python and Bootstrap.
55 </p> 61 </p>
56 <p class="lead mb-4">Посилання на репозиторій: {{selected_component.git_link}}</p> 62 <p class="lead mb-4">Посилання на репозиторій: {{selected_component.git_link}}</p>
57 <p class="lead mb-4">Версія: {{selected_component.version}}</p> 63 <p class="lead mb-4">Версія: {{selected_component.version}}</p>
58 <p class="lead mb-4">Розробка: K2 Cloud</p> 64 <p class="lead mb-4">Розробка: K2 Cloud</p>
59 <div class="d-grid gap-2 d-sm-flex justify-content-sm-center mb-5"> 65 <div class="d-grid gap-2 d-sm-flex justify-content-sm-center mb-5">
60 66
61 <a href="/install_components/{{ selected_component.id }}" id="installBtn" class="btn btn-primary btn-lg px-4 me-sm-3" onclick="showLoader()">Встановити компоненту</a> 67 <a href="/install_components/{{ selected_component.id }}" id="installBtn" class="btn btn-primary btn-lg px-4 me-sm-3" onclick="showLoader()">Встановити компоненту</a>
62 </div> 68 </div>
63 </div> 69 </div>
64 <div class="overflow-hidden" style="max-height: 30vh;"> 70 <div class="overflow-hidden" style="max-height: 30vh;">
65 <div class="container px-5"> 71 <div class="container px-5">
66 <img src="https://corp2.eu/media/assets/images/service/k2cloud.jpg" class="img-fluid border rounded-3 shadow-lg mb-4" alt="Example image" width="700" height="500" loading="lazy"> 72 <img src="https://corp2.eu/media/assets/images/service/k2cloud.jpg" class="img-fluid border rounded-3 shadow-lg mb-4" alt="Example image" width="700" height="500" loading="lazy">
67 </div> 73 </div>
68 </div> 74 </div>
69 </div> 75 </div>
70 76
71 {% else %} 77 {% else %}
72 Помилка завантаження компоненти з сервера 78 Помилка завантаження компоненти з сервера
73 {% endif %} 79 {% endif %}
74 80
75 <script> 81 <script>
76 function showLoader() { 82 function showLoader() {
77 document.getElementById("popupBackdrop").style.display = "block"; 83 document.getElementById("popupBackdrop").style.display = "block";
78 } 84 }
79 85
80 function hideLoader() { 86 function hideLoader() {
81 document.getElementById("popupBackdrop").style.display = "none"; 87 document.getElementById("popupBackdrop").style.display = "none";
82 } 88 }
83 89
84 window.onload = function() { 90 window.onload = function() {
85 hideLoader(); 91 hideLoader();
86 }; 92 };
87 </script> 93 </script>
88 94
89 95
90 {% endblock %} 96 {% endblock %}
97
98 <footer>
templates/dashboard-add.html
1 {% extends 'base.html' %} 1 {% extends 'base.html' %}
2 2
3
4 {% block styles %} 3 {% block styles %}
5 <style> 4 <style>
6 .table { 5 .table {
7 border-collapse: collapse; 6 border-collapse: collapse;
8 width: 100%; 7 width: 100%;
9 } 8 }
10 9
11 .table th, .table td { 10 .table th, .table td {
12 text-align: left; 11 text-align: left;
13 padding: 8px; 12 padding: 8px;
14 border-bottom: 1px solid #ddd; 13 border-bottom: 1px solid #ddd;
15 } 14 }
16 15
17 .table tr:hover { 16 .table tr:hover {
18 background-color: #f5f5f5; 17 background-color: #f5f5f5;
19 } 18 }
20 19
21 .search-form { 20 .search-form {
22 margin-bottom: 20px; 21 margin-bottom: 20px;
23 } 22 }
24 23
25 .search-form .input-group { 24 .search-form .input-group {
26 width: 300px; 25 width: 300px;
27 } 26 }
28 </style> 27 </style>
29 {% endblock %} 28 {% endblock %}
30 <!DOCTYPE html>
31 <html>
32 <head>
33 <title>{% block title %}{% endblock %}</title>
34 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
35 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
36 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
37 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
38 <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
39 29
40
41 </head>
42 <body>
43
44 <div class="content"> 30 <div class="content">
45 {% block content %} 31 {% block content %}
46 32
47 <div class="container px-4 py-5" id="hanging-icons"> 33 <div class="container px-4 py-5" id="hanging-icons">
48 <h2 class="pb-2 border-bottom">{{gettext('t_components_shop')}}</h2> 34 <h2 class="pb-2 border-bottom">{{gettext('t_components_shop')}}</h2>
49 <form action="{{ url_for('components.dashboard') }}" method="GET" class="search-form"> 35 <form action="{{ url_for('components.dashboard') }}" method="GET" class="search-form">
50 <div class="input-group"> 36 <div class="input-group">
51 <input type="text" name="search_query" class="form-control" placeholder="Search components"> 37 <input type="text" name="search_query" class="form-control" placeholder="Search components">
52 <button type="submit" class="btn btn-primary">Search</button> 38 <button type="submit" class="btn btn-primary">Search</button>
53 </div> 39 </div>
54 </form> 40 </form>
55 41
56 42
57 <div class="row g-4 py-5 row-cols-1 row-cols-lg-3"> 43 <div class="row g-4 py-5 row-cols-1 row-cols-lg-3">
58 {% if component_server %} 44 {% if component_server %}
59 {% for component in component_server %} 45 {% for component in component_server %}
60 <div class="col d-flex align-items-start"> 46 <div class="col d-flex align-items-start">
61 <div class="icon-square bg-light text-dark flex-shrink-0 me-3"> 47 <div class="icon-square bg-light text-dark flex-shrink-0 me-3">
62 <img class="d-block mx-auto mb-4" src="/static/img/logo-k2.png" alt="" width="60"> 48 <img class="d-block mx-auto mb-4" src="/static/img/logo-k2.png" alt="" width="60">
63 </div> 49 </div>
64 <div> 50 <div>
65 <h2>{{ component.name|title }}</h2> 51 <h2>{{ component.name|title }}</h2>
66 <p>{{ component.description }}</p> 52 <p>{{ component.description }}</p>
67 <p>ВЕРСІЯ {{ component.latest_version }}</p> 53 <p>version {{ component.latest_version }}</p>
68 {% if component.name in components_names %} 54 {% if component.name in components_names %}
69 <button type="button" class="btn btn-success">Installed</button> 55 <button type="button" class="btn btn-success">Installed</button>
70 {% else %} 56 {% else %}
71 <a href="" class="btn btn-primary">Install</a> 57 <a href="/show_components-site/{{ component.id }}" class="btn btn-primary">Install</a>
72 {% endif %} 58 {% endif %}
73 </div> 59 </div>
74 </div> 60 </div>
75 {% endfor %} 61 {% endfor %}
76 {% else %} 62 {% else %}
77 <div class="col"> 63 <div class="col">
78 <p>No components available.</p> 64 <p>No components available.</p>
79 </div> 65 </div>
80 {% endif %} 66 {% endif %}
81 </div> 67 </div>
82 </div> 68 </div>
83 69
84 {% endblock %} 70 {% endblock %}
85 71
86 72
87 </div> 73 </div>
88
89 </body>
90 </html>
templates/dashboard-list.html
1 {% extends 'base.html' %} 1 {% extends 'base.html' %}
2 2
3 {% block styles %} 3 {% block styles %}
4 <style> 4 <style>
5 .table { 5 .table {
6 border-collapse: collapse; 6 border-collapse: collapse;
7 width: 100%; 7 width: 100%;
8 } 8 }
9 9
10 .table th, .table td { 10 .table th, .table td {
11 text-align: left; 11 text-align: left;
12 padding: 8px; 12 padding: 8px;
13 border-bottom: 1px solid #ddd; 13 border-bottom: 1px solid #ddd;
14 } 14 }
15 15
16 .table tr:hover { 16 .table tr:hover {
17 background-color: #f5f5f5; 17 background-color: #f5f5f5;
18 } 18 }
19 19
20 .search-form { 20 .search-form {
21 margin-bottom: 20px; 21 margin-bottom: 20px;
22 } 22 }
23 23
24 .search-form .input-group { 24 .search-form .input-group {
25 width: 300px; 25 width: 300px;
26 } 26 }
27 </style> 27 </style>
28 {% endblock %} 28 {% endblock %}
29 <!DOCTYPE html>
30 <html>
31 <head>
32 <title>{% block title %}{% endblock %}</title>
33 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
34 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
35 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
36 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
37 <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
38
39
40 </head>
41 <body>
42
43 <div class="content"> 29 <div class="content">
44 {% block content %} 30 {% block content %}
45 31
46 <h2>{{ gettext('t_installed_components') }}</h2> 32 <h2>{{ gettext('t_installed_components') }}</h2>
47 33
48 <table class="table"> 34 <table class="table">
49 <thead> 35 <thead>
50 <tr> 36 <tr>
51 <th>{{gettext('t_name')}}</th> 37 <th>{{gettext('t_name')}}</th>
52 <th>{{gettext('t_description')}}</th> 38 <th>{{gettext('t_description')}}</th>
53 <th>{{gettext('t_version')}}</th> 39 <th>{{gettext('t_version')}}</th>
54 <th>{{gettext('t_dependencies')}}</th>
55 <th>{{gettext('t_git_link')}}</th> 40 <th>{{gettext('t_git_link')}}</th>
56 <th>{{gettext('t_install_at')}}</th> 41 <th>{{gettext('t_install_at')}}</th>
57 <th>{{gettext('t_status')}}</th> 42 <th>{{gettext('t_status')}}</th>
58 <th>{{gettext('t_action')}}</th> 43 <th>{{gettext('t_action')}}</th>
59 </tr> 44 </tr>
60 </thead> 45 </thead>
61 46
62 <tbody> 47 <tbody>
63 <tr> 48 <tr>
64 <td>k2root</td> 49 <td>k2root</td>
65 <td>main component</td> 50 <td>main component</td>
66 <td colspan="6">2.5.1.27</td></tr> 51 <td colspan="6">2.5.1.27</td></tr>
67 52
68 {% for component in components %} 53 {% for component in components %}
69 <tr> 54 <tr>
70 <td>{{ component.name }}</td> 55 <td>{{ component.name }}</td>
71 <td>{{ component.description }}</td> 56 <td>{{ component.description }}</td>
72 <td>{{ component.version }}</td> 57 <td>{{ component.version }}</td>
73 <td>{{ component.dependencies }}</td>
74 <td>{{ component.git_link }}</td> 58 <td>{{ component.git_link }}</td>
75 <td>{{ component.date_installed }}</td> 59 <td>{{ component.date_installed }}</td>
76 <td> 60 <td>
77 {% if component.installed %} 61 {% if component.installed %}
78 Yes 62 Yes
79 {% else %} 63 {% else %}
80 No 64 No
81 {% endif %} 65 {% endif %}
82 </td> 66 </td>
83 <td> 67 <td>
84 {% if component.installed %} 68 {% if component.installed %}
85 <a href="/remove_dependencies/{{ component.id }}" class="btn btn-primary">Вимкнути</a> 69 <a href="/remove_dependencies/{{ component.id }}" class="btn btn-primary">{{gettext('t_turn_of_component')}}</a>
86 {% else %} 70 {% else %}
87 <a href="/add_dependencies/{{ component.id }}" class="btn btn-primary">Увімкнути</a> 71 <a href="/add_dependencies/{{ component.id }}" class="btn btn-primary">{{gettext('t_turn_on_component')}}</a>
88 <!-- Button trigger modal --> 72 <!-- Button trigger modal -->
89 <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#components-{{ component.id }}"> 73 <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#components-{{ component.id }}">
90 Видалити 74 {{gettext('t_delete_popup')}}
91 </button> 75 </button>
92 76
93 <!-- Modal --> 77 <!-- Modal -->
94 <div class="modal fade" id="components-{{ component.id }}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> 78 <div class="modal fade" id="components-{{ component.id }}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
95 <div class="modal-dialog"> 79 <div class="modal-dialog">
96 <div class="modal-content"> 80 <div class="modal-content">
97 <div class="modal-header"> 81 <div class="modal-header">
98 <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1> 82 <h1 class="modal-title fs-5" id="exampleModalLabel">Title</h1>
99 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 83 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
100 </div> 84 </div>
101 <div class="modal-body"> 85 <div class="modal-body">
102 Видалити компоненту? 86 {{gettext('t_components_delete')}}?
103 </div> 87 </div>
104 <div class="modal-footer"> 88 <div class="modal-footer">
105 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> 89 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{gettext('t_close_popup')}}</button>
106 <a href="/remove-component/{{ component.id }}" class="btn btn-danger">Видалити</a> 90 <a href="/remove-component/{{ component.id }}" class="btn btn-danger">{{gettext('t_delete_popup')}}</a>
107 </div> 91 </div>
108 </div> 92 </div>
109 </div> 93 </div>
110 </div> 94 </div>
111 {% endif %} 95 {% endif %}
112 </td> 96 </td>
113 </tr> 97 </tr>
114 {% endfor %} 98 {% endfor %}
115 </tbody> 99 </tbody>
116 </table> 100 </table>
117 101
118 102
119 103
120
121 {% endblock %} 104 {% endblock %}
122 105
123
124 </div> 106 </div>
125
126 </body>
127 </html>
templates/dashboard.html
1 1
2 2
3 {% block styles %} 3 {% block styles %}
4 <style> 4 <style>
5 .table { 5 .table {
6 border-collapse: collapse; 6 border-collapse: collapse;
7 width: 100%; 7 width: 100%;
8 } 8 }
9 9
10 .table th, .table td { 10 .table th, .table td {
11 text-align: left; 11 text-align: left;
12 padding: 8px; 12 padding: 8px;
13 border-bottom: 1px solid #ddd; 13 border-bottom: 1px solid #ddd;
14 } 14 }
15 15
16 .table tr:hover { 16 .table tr:hover {
17 background-color: #f5f5f5; 17 background-color: #f5f5f5;
18 } 18 }
19 19
20 .search-form { 20 .search-form {
21 margin-bottom: 20px; 21 margin-bottom: 20px;
22 } 22 }
23 23
24 .search-form .input-group { 24 .search-form .input-group {
25 width: 300px; 25 width: 300px;
26 } 26 }
27 </style> 27 </style>
28 {% endblock %} 28 {% endblock %}
29 <!DOCTYPE html> 29 <!DOCTYPE html>
30 <html> 30 <html>
31 <head> 31 <head>
32 <title>{% block title %}{% endblock %}</title> 32 <title>{% block title %}{% endblock %}</title>
33 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}"> 33 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
34 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}"> 34 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
35 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous"> 35 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
36 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script> 36 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
37 <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> 37 <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
38 38
39 39
40 </head> 40 </head>
41 <body> 41 <body>
42 42
43 <div class="content"> 43 <div class="content">
44 {% block content %} 44 {% block content %}
45 <h1>K2CloudERP-2.5.1.27</h1> 45 <h1>K2CloudERP-2.5.1.27</h1>
46 <p> <a href="{{ url_for('components.change_language', lang='en') }}">en</a> | <a href="{{ url_for('components.change_language', lang='pl') }}">pl</a> | <a href="">uk</a></p> 46 <p> <a href="{{ url_for('components.change_language', lang='en') }}">en</a> | <a href="{{ url_for('components.change_language', lang='pl') }}">pl</a> | <a href="{{ url_for('components.change_language', lang='uk') }}">uk</a></p>
47 {{language}} 47 {{language}}
48 48
49 49
50 <h2>{{ gettext('t_installed_components') }}</h2> 50 <h2>{{ gettext('t_installed_components') }}</h2>
51 51
52 <table class="table"> 52 <table class="table">
53 <thead> 53 <thead>
54 <tr> 54 <tr>
55 <th>{{gettext('t_name')}}</th> 55 <th>{{gettext('t_name')}}</th>
56 <th>{{gettext('t_description')}}</th> 56 <th>{{gettext('t_description')}}</th>
57 <th>{{gettext('t_version')}}</th> 57 <th>{{gettext('t_version')}}</th>
58 <th>{{gettext('t_dependencies')}}</th> 58 <th>{{gettext('t_dependencies')}}</th>
59 <th>{{gettext('t_git_link')}}</th> 59 <th>{{gettext('t_git_link')}}</th>
60 <th>{{gettext('t_install_at')}}</th> 60 <th>{{gettext('t_install_at')}}</th>
61 <th>{{gettext('t_status')}}</th> 61 <th>{{gettext('t_status')}}</th>
62 <th>{{gettext('t_action')}}</th> 62 <th>{{gettext('t_action')}}</th>
63 </tr> 63 </tr>
64 </thead> 64 </thead>
65 65
66 <tbody> 66 <tbody>
67 <tr> 67 <tr>
68 <td>k2root</td> 68 <td>k2root</td>
69 <td>main component</td> 69 <td>main component</td>
70 <td colspan="6">2.5.1.27</td></tr> 70 <td colspan="6">2.5.1.27</td></tr>
71 71
72 {% for component in components %} 72 {% for component in components %}
73 <tr> 73 <tr>
74 <td>{{ component.name }}</td> 74 <td>{{ component.name }}</td>
75 <td>{{ component.description }}</td> 75 <td>{{ component.description }}</td>
76 <td>{{ component.version }}</td> 76 <td>{{ component.version }}</td>
77 <td>{{ component.dependencies }}</td> 77 <td>{{ component.dependencies }}</td>
78 <td>{{ component.git_link }}</td> 78 <td>{{ component.git_link }}</td>
79 <td>{{ component.date_installed }}</td> 79 <td>{{ component.date_installed }}</td>
80 <td> 80 <td>
81 {% if component.installed %} 81 {% if component.installed %}
82 Yes 82 Yes
83 {% else %} 83 {% else %}
84 No 84 No
85 {% endif %} 85 {% endif %}
86 </td> 86 </td>
87 <td> 87 <td>
88 {% if component.installed %} 88 {% if component.installed %}
89 <a href="/remove_dependencies/{{ component.id }}" class="btn btn-primary">Вимкнути</a> 89 <a href="/remove_dependencies/{{ component.id }}" class="btn btn-primary">Вимкнути</a>
90 {% else %} 90 {% else %}
91 <a href="/add_dependencies/{{ component.id }}" class="btn btn-primary">Увімкнути</a> 91 <a href="/add_dependencies/{{ component.id }}" class="btn btn-primary">Увімкнути</a>
92 <!-- Button trigger modal --> 92 <!-- Button trigger modal -->
93 <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#components-{{ component.id }}"> 93 <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#components-{{ component.id }}">
94 Видалити 94 Видалити
95 </button> 95 </button>
96 96
97 <!-- Modal --> 97 <!-- Modal -->
98 <div class="modal fade" id="components-{{ component.id }}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> 98 <div class="modal fade" id="components-{{ component.id }}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
99 <div class="modal-dialog"> 99 <div class="modal-dialog">
100 <div class="modal-content"> 100 <div class="modal-content">
101 <div class="modal-header"> 101 <div class="modal-header">
102 <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1> 102 <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
103 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 103 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
104 </div> 104 </div>
105 <div class="modal-body"> 105 <div class="modal-body">
106 Видалити компоненту? 106 Видалити компоненту?
107 </div> 107 </div>
108 <div class="modal-footer"> 108 <div class="modal-footer">
109 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> 109 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
110 <a href="/remove-component/{{ component.id }}" class="btn btn-danger">Видалити</a> 110 <a href="/remove-component/{{ component.id }}" class="btn btn-danger">Видалити</a>
111 </div> 111 </div>
112 </div> 112 </div>
113 </div> 113 </div>
114 </div> 114 </div>
115 {% endif %} 115 {% endif %}
116 </td> 116 </td>
117 </tr> 117 </tr>
118 {% endfor %} 118 {% endfor %}
119 </tbody> 119 </tbody>
120 </table> 120 </table>
121 121
122 122
123 123
124 124
125 125
126 126
127 <div class="container px-4 py-5" id="hanging-icons"> 127 <div class="container px-4 py-5" id="hanging-icons">
128 <h2 class="pb-2 border-bottom">{{gettext('t_components_shop')}}</h2> 128 <h2 class="pb-2 border-bottom">{{gettext('t_components_shop')}}</h2>
129 <form action="{{ url_for('components.dashboard') }}" method="GET" class="search-form"> 129 <form action="{{ url_for('components.dashboard') }}" method="GET" class="search-form">
130 <div class="input-group"> 130 <div class="input-group">
131 <input type="text" name="search_query" class="form-control" placeholder="Search components"> 131 <input type="text" name="search_query" class="form-control" placeholder="Search components">
132 <button type="submit" class="btn btn-primary">Search</button> 132 <button type="submit" class="btn btn-primary">Search</button>
133 </div> 133 </div>
134 </form> 134 </form>
135 135
136 136
137 <div class="row g-4 py-5 row-cols-1 row-cols-lg-3"> 137 <div class="row g-4 py-5 row-cols-1 row-cols-lg-3">
138 {% if component_server %} 138 {% if component_server %}
139 {% for component in component_server %} 139 {% for component in component_server %}
140 <div class="col d-flex align-items-start"> 140 <div class="col d-flex align-items-start">
141 <div class="icon-square bg-light text-dark flex-shrink-0 me-3"> 141 <div class="icon-square bg-light text-dark flex-shrink-0 me-3">
142 <img class="d-block mx-auto mb-4" src="/static/img/logo-k2.png" alt="" width="60"> 142 <img class="d-block mx-auto mb-4" src="/static/img/logo-k2.png" alt="" width="60">
143 </div> 143 </div>
144 <div> 144 <div>
145 <h2>{{ component.name|title }}</h2> 145 <h2>{{ component.name|title }}</h2>
146 <p>{{ component.description }}</p> 146 <p>{{ component.description }}</p>
147 <p>ВЕРСІЯ {{ component.latest_version }}</p> 147 <p>ВЕРСІЯ {{ component.latest_version }}</p>
148 {% if component.name in components_names %} 148 {% if component.name in components_names %}
149 <button type="button" class="btn btn-success">Installed</button> 149 <button type="button" class="btn btn-success">Installed</button>
150 {% else %} 150 {% else %}
151 <a href="/show_components/{{ component.id }}" class="btn btn-primary">Install</a> 151 <a href="/show_components/{{ component.id }}" class="btn btn-primary">Install</a>
152 {% endif %} 152 {% endif %}
153 </div> 153 </div>
154 </div> 154 </div>
155 {% endfor %} 155 {% endfor %}
156 {% else %} 156 {% else %}
157 <div class="col"> 157 <div class="col">
158 <p>No components available.</p> 158 <p>No components available.</p>
159 </div> 159 </div>
160 {% endif %} 160 {% endif %}
161 </div> 161 </div>
162 </div> 162 </div>
163 163
164 {% endblock %} 164 {% endblock %}
165 <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 165 <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
166 <footer> 166 <footer>
167 &copy; 2023 Корпорація k2 167 &copy; 2023 Корпорація k2
168 </footer> 168 </footer>
169 169
170 </div> 170 </div>
171 171
172 </body> 172 </body>
173 </html> 173 </html>
File was created 1 select:
2 select menuid, namemenu, scriptrun, prevmenu, prevmenu_text, module_name, del, active,
3 createuser, createdate, updateuser, updatedate, order_ins, caption, url/*, t */
4 from k2admin_menus
5
6 table: k2admin_menus
7 sortname: order_ins
8 typeid: 1
9
10 # Детально
11 detile: admin_menu_prav
12
13 addtool_button:
14 0:
15 caption: Синхр.
16 title: Загрузка списка пунктов меню
17 id: rights
18 icon: "ui-icon-extlink"
19 action: "loadMenuItems()"
20 position: last
21
22 height: 150
23
24 sortorder: asc
25 caption: Доступ к меню
26 fields:
27 menuid:
28 field: menuid
29 caption: ID
30 width: 40
31 readonly: true
32 align: left
33 hidden: true
34 type_field: text
35 primary_key: true
36
37 caption:
38 field: caption
39 caption: Меню
40 width: 400
41 readonly: false
42 align: left
43 type_field: text
44
45 namemenu:
46 field: namemenu
47 caption: Идентификатор меню
48 width: 200
49 readonly: false
50 align: left
51 hidden: false
52 type_field: text
53
54 module_name:
55 field: module_name
56 caption: Название модуля
57 width: 200
58 readonly: false
59 align: left
60 hidden: false
61 type_field: text
62
63 # t:
64 # field: t
65 # caption: Параметр t
66 # width: 100
67 # readonly: false
68 # align: left
69 # hidden: false
70
71 url:
72 field: url
73 caption: URL
74 width: 250
75 readonly: false
76 align: left
77 hidden: false
78 type_field: text
79
80 order_ins:
81 field: order_ins
82 caption: Сортировка
83 width: 75
84 readonly: false
85 align: left
86 hidden: false
87 type_field: text
88
89 active:
90 field: active
91 caption: Акт.
92 width: 50
93 readonly: false
94 type_field: checkbox
95 def_value: 1
96 align: center
97
98 del:
99 field: del
100 caption: Удал.
101 width: 50
102 readonly: false
103 type_field: checkbox
104 def_value: 0
105 align: center
106 hidden: true
107
yml/admin_menu_prav.yml
File was created 1 select:
2 select m.pravrepid, m.menuid, m.username, m.r, m.w, m.i, m.d, m.c,
3 m.exp, m.imp, m.settable, m.cutpast, m.enable, m.magazinsid, m.del,
4 m.active, m.createuser, m.createdate, m.updateuser, m.updatedate, m.order_ins,
5 m.roleid, r.rolename from k2admin_menus_prava m
6
7 left join k2roles r
8 on m.roleid = r.roleid
9
10 table: k2admin_menus_prava
11 sortname: pravrepid
12 typeid: 1
13
14 height: 590
15
16 where: " WHERE (menuid='{masterid}') "
17 getmaster: true
18 masterid: menuid
19
20 sortorder: asc
21 caption: Права
22 fields:
23 pravrepid:
24 field: pravrepid
25 alias: m.pravrepid
26 caption: ID
27 width: 40
28 readonly: true
29 align: left
30 hidden: true
31 primary_key: true
32
33 roleid:
34 field: roleid
35 alias: m.roleid
36 caption: ID ролі
37 width: 200
38 readonly: false
39 align: left
40 type_field: DropDown
41 multy: false
42 hidden: true
43 sql:
44 select roleid as k, rolename as v
45 from k2roles
46 order by rolename
47
48 rolename:
49 field: rolename
50 caption: Права
51 alias: r.rolename
52
53 username:
54 field: username
55 alias: m.username
56 caption: Пользователь
57 width: 150
58 readonly: false
59 align: left
60
61 r:
62 field: r
63 alias: m.r
64 caption: Чтение
65 width: 50
66 readonly: false
67 align: center
68 type_field: checkbox
69 def_value: 1
70
71 w:
72 field: w
73 alias: m.w
74 caption: Запись
75 width: 50
76 readonly: false
77 align: center
78 type_field: checkbox
79 def_value: 1
80
81 i:
82 field: i
83 alias: m.i
84 caption: Вставка
85 width: 50
86 readonly: false
87 align: center
88 type_field: checkbox
89 def_value: 1
90
91 d:
92 field: d
93 alias: m.d
94 caption: Удаление
95 width: 50
96 readonly: false
97 align: center
98 type_field: checkbox
99 def_value: 1
100
101 c:
102 field: c
103 alias: m.c
104 caption: Копирование
105 width: 50
106 readonly: false
107 align: center
108 type_field: checkbox
109 def_value: 0
110
111 exp:
112 field: exp
113 alias: m.exp
114 caption: Экспорт
115 width: 50
116 readonly: false
117 align: center
118 type_field: checkbox
119 def_value: 0
120
121 imp:
122 field: imp
123 alias: m.imp
124 caption: Импорт
125 width: 50
126 readonly: false
127 align: center
128 type_field: checkbox
129 def_value: 0
130
131 settable:
132 field: settable
133 alias: m.settable
134 caption: "Настройка<br>таблиц"
135 width: 50
136 readonly: false
137 align: center
138 type_field: checkbox
139 def_value: 1
140
141 cutpast:
142 field: cutpast
143 alias: m.cutpast
144 caption: "Копирование<br>в буфер"
145 width: 50
146 readonly: false
147 align: center
148 type_field: checkbox
149 def_value: 1
150
151 enable:
152 field: enable
153 alias: m.enable
154 caption: "Активность<br>элементов"
155 width: 50
156 readonly: false
157 align: center
158 type_field: checkbox
159 def_value: 1
160
161 active:
162 field: active
163 alias: m.active
164 caption: Акт.
165 width: 50
166 readonly: false
167 align: left
168 type_field: checkbox
169 def_value: 1
170
171 del:
172 field: del
173 alias: m.del
174 caption: Удал.
175 width: 50
176 readonly: false
177 align: left
178 type_field: checkbox
179 def_value: 0
180 hidden: true
181
yml/gruntcontrols.yml
1 select: 1 select:
2 select g.gruntcontrolid, g.zajavkid, g.VirobnikId, g.num, g.cultid, g.sortid, g.catid, g.genid, g.mass_part, g.partnum, g.agronomid, g.posvnum, g.actnum, g.actdate, g.oblastid, g.posada, g.vidpravlenoid, 2 select g.gruntcontrolid, g.zajavkid, g.VirobnikId, g.num, g.cultid, g.sortid, g.catid, g.genid, g.mass_part, g.partnum, g.agronomid, g.posvnum, g.actnum, g.actdate, g.oblastid, g.posada, g.vidpravlenoid,
3 g.factnadhid, g.zvitnum, g.zvitdate, g.sortchyst, g.oplataid, g.active, g.usercreate, g.datecreate, g.userupdate, g.dateupdate, g.dogstatusid, g.gruntcontrol_year, g.firmid, 3 g.factnadhid, g.zvitnum, g.zvitdate, g.sortchyst, g.oplataid, g.active, g.usercreate, g.datecreate, g.userupdate, g.dateupdate, g.dogstatusid, g.gruntcontrol_year, g.firmid,
4 4
5 z.zajavn, obl.OblastNameUA, s.NameUA, k.Kultura, ge.generation_name, c.cat_name, a.fio, a.dp_posad_name, ds.statusname, 5 z.zajavn, obl.OblastNameUA, s.NameUA, k.Kultura, ge.generation_name, c.cat_name, a.fio, a.dp_posad_name, ds.statusname,
6 v.name as vname, o.name as oname, fn.name as fnname, uc.login as uclogin, uu.login as uulogin, vyr.VirobnikNameUA, f.name_firm 6 v.name as vname, o.name as oname, fn.name as fnname, uc.login as uclogin, uu.login as uulogin, vyr.VirobnikNameUA, f.name_firm
7 7
8 from dp2_gruntcontrols g 8 from dp2_gruntcontrols g
9 9
10 left join dp2_zajavka_obsteg z 10 left join dp2_zajavka_obsteg z
11 on g.zajavkid = z.zajavkid 11 on g.zajavkid = z.zajavkid
12 12
13 left join k2firms f 13 left join k2firms f
14 on g.firmid = f.firmid 14 on g.firmid = f.firmid
15 15
16 left join dp2Virobn vyr 16 left join dp2Virobn vyr
17 on g.VirobnikId = vyr.VirobnikId 17 on g.VirobnikId = vyr.VirobnikId
18 18
19 left join dp2Kultur k 19 left join dp2Kultur k
20 on g.cultid=k.CodKult 20 on g.cultid=k.CodKult
21 21
22 left join dp2SortReestr s 22 left join dp2SortReestr s
23 on g.sortid=s.SortID 23 on g.sortid=s.SortID
24 24
25 left join dp2Categors c 25 left join dp2Categors c
26 on g.catid=c.catid 26 on g.catid=c.catid
27 27
28 left join dp2generation ge 28 left join dp2generation ge
29 on g.genid=ge.generationid 29 on g.genid=ge.generationid
30 30
31 left join dp2_auditors a 31 left join dp2_auditors a
32 on g.agronomid=a.auditid 32 on g.agronomid=a.auditid
33 33
34 left join dp2_grunt_factnadh fn 34 left join dp2_grunt_factnadh fn
35 on g.factnadhid = fn.factnadhid 35 on g.factnadhid = fn.factnadhid
36 36
37 left join dp2_grunt_oplat o 37 left join dp2_grunt_oplat o
38 on g.oplataid = o.oplataid 38 on g.oplataid = o.oplataid
39 39
40 left join dp2_grunt_vidprav v 40 left join dp2_grunt_vidprav v
41 on g.vidpravlenoid = v.vidpravlenoid 41 on g.vidpravlenoid = v.vidpravlenoid
42 42
43 left join dp2Oblast obl 43 left join dp2Oblast obl
44 ON g.oblastid = obl.OblastId 44 ON g.oblastid = obl.OblastId
45 45
46 left join k2users uc 46 left join k2users uc
47 on g.usercreate = uc.user_id 47 on g.usercreate = uc.user_id
48 48
49 left join k2users uu 49 left join k2users uu
50 on g.userupdate = uu.user_id 50 on g.userupdate = uu.user_id
51 51
52 left join dp2_grunt_dogstatus ds 52 left join dp2_grunt_dogstatus ds
53 on g.dogstatusid = ds.dogstatusid 53 on g.dogstatusid = ds.dogstatusid
54 54
55 where: "where (g.actdate >= '<%year%>-01-01') and (g.actdate <= '<%year%>-12-31') and (z.oblastid='<%oblid%>' or g.oblastid IN (<%listoblid%>) or '<%ROLE%>'='-1' or '<%ROLE%>'='acd5f33a70b6b05512e5859aa9c0115d' ) " 55 where: "where (g.actdate >= '<%year%>-01-01') and (g.actdate <= '<%year%>-12-31') and (z.oblastid='<%oblid%>' or g.oblastid IN (<%listoblid%>) or '<%ROLE%>'='-1' or '<%ROLE%>'='acd5f33a70b6b05512e5859aa9c0115d' ) "
56 table: dp2_gruntcontrols 56 table: dp2_gruntcontrols
57 typeid: 1 57 typeid: 1
58 sortname: num 58 sortname: num
59 sortorder: desc 59 sortorder: desc
60 caption: Грунтконтроль 60 caption: Грунтконтроль
61 detile: dp2_files_grunt 61 detile: dp2_files_grunt
62 onRightClickRow: contMenu(rowid) 62 onRightClickRow: contMenu(rowid)
63 height: 350 63 height: 350
64 rows: 20 64 rows: 20
65 custom_form: true 65 custom_form: true
66 form_width: 825 66 form_width: 825
67 form_height: 420 67 form_height: 420
68 is_add: false 68 is_add: false
69 is_del: false 69 is_del: false
70 is_edit: false 70 is_edit: false
71 footer: true 71 footer: true
72 after_save_script: afterSave(); 72 after_save_script: afterSave();
73 fields: 73 fields:
74 gruntcontrolid: 74 gruntcontrolid:
75 field: gruntcontrolid 75 field: gruntcontrolid
76 caption: ID 76 caption: ID
77 width: 120 77 width: 120
78 hidden: true 78 hidden: true
79 readonly: true 79 readonly: true
80 align: center 80 align: center
81 type_field: text 81 type_field: text
82 primary_key: true
82 83
83 zajavkid: 84 zajavkid:
84 field: zajavn 85 field: zajavn
85 caption: Заявка № 86 caption: Заявка №
86 alias: z.zajavn 87 alias: z.zajavn
87 width: 65 88 width: 65
88 readonly: true 89 readonly: true
89 align: right 90 align: right
90 disabled: true 91 disabled: true
91 width_form: 220 92 width_form: 220
92 main_filter: true 93 main_filter: true
93 formoptions: 94 formoptions:
94 rowpos: 1 95 rowpos: 1
95 colpos: 2 96 colpos: 2
96 type_field: text 97 type_field: text
97 98
98 firms: 99 firms:
99 field: name_firm 100 field: name_firm
100 alias: f.name_firm 101 alias: f.name_firm
101 caption: Назва компанії 102 caption: Назва компанії
102 alias_form: firmid 103 alias_form: firmid
103 type_fieldform: DropDown 104 type_fieldform: DropDown
104 sql_form: select firmid as k, name_firm as v from k2firms 105 sql_form: select firmid as k, name_firm as v from k2firms
105 width: 150 106 width: 150
106 hidden_form: true 107 hidden_form: true
107 type_field: text 108 type_field: text
108 align: left 109 align: left
109 width_form: 220 110 width_form: 220
110 111
111 num: 112 num:
112 field: num 113 field: num
113 alias: g.num 114 alias: g.num
114 caption: № 115 caption: №
115 width: 75 116 width: 75
116 readonly: false 117 readonly: false
117 align: right 118 align: right
118 disabled: true 119 disabled: true
119 width_form: 220 120 width_form: 220
120 formoptions: 121 formoptions:
121 rowpos: 2 122 rowpos: 2
122 colpos: 0 123 colpos: 0
123 type_field: text 124 type_field: text
124 125
125 gruntcontrol_year: 126 gruntcontrol_year:
126 field: gruntcontrol_year 127 field: gruntcontrol_year
127 alias: g.gruntcontrol_year 128 alias: g.gruntcontrol_year
128 caption: Рік 129 caption: Рік
129 width: 75 130 width: 75
130 readonly: true 131 readonly: true
131 align: right 132 align: right
132 disabled: true 133 disabled: true
133 width_form: 220 134 width_form: 220
134 type_field: text 135 type_field: text
135 formoptions: 136 formoptions:
136 rowpos: 3 137 rowpos: 3
137 colpos: 0 138 colpos: 0
138 139
139 oblastid: 140 oblastid:
140 field: OblastNameUA 141 field: OblastNameUA
141 alias: obl.OblastNameUA 142 alias: obl.OblastNameUA
142 caption: Область 143 caption: Область
143 width: 100 144 width: 100
144 readonly: false 145 readonly: false
145 align: left 146 align: left
146 type_fieldform: DropDown 147 type_fieldform: DropDown
147 alias_form: oblastid 148 alias_form: oblastid
148 sql_form: select OblastId as k, OblastNameUA as v from dp2Oblast order by OblastNameUA 149 sql_form: select OblastId as k, OblastNameUA as v from dp2Oblast order by OblastNameUA
149 formoptions: 150 formoptions:
150 rowpos: 4 151 rowpos: 4
151 colpos: 0 152 colpos: 0
152 width_form: 220 153 width_form: 220
153 main_filter: true 154 main_filter: true
154 type_field: text 155 type_field: text
155 156
156 VirobnikId: 157 VirobnikId:
157 field: VirobnikNameUA 158 field: VirobnikNameUA
158 alias: vyr.VirobnikNameUA 159 alias: vyr.VirobnikNameUA
159 caption: Контрагент 160 caption: Контрагент
160 width: 150 161 width: 150
161 readonly: false 162 readonly: false
162 align: left 163 align: left
163 type_fieldform: DropDown 164 type_fieldform: DropDown
164 alias_form: VirobnikId 165 alias_form: VirobnikId
165 sql: select VirobnikId as k, VirobnikNameUA as v from dp2Virobn order by VirobnikNameUA 166 sql: select VirobnikId as k, VirobnikNameUA as v from dp2Virobn order by VirobnikNameUA
166 is_book: true 167 is_book: true
167 sql_form: select VirobnikId as k, VirobnikNameUA as v from dp2Virobn where active = 1 order by VirobnikNameUA 168 sql_form: select VirobnikId as k, VirobnikNameUA as v from dp2Virobn where active = 1 order by VirobnikNameUA
168 formoptions: 169 formoptions:
169 rowpos: 5 170 rowpos: 5
170 colpos: 0 171 colpos: 0
171 width_form: 190 172 width_form: 190
172 main_filter: true 173 main_filter: true
173 type_field: text 174 type_field: text
174 175
175 VirobnikId2: 176 VirobnikId2:
176 field: VirobnikId 177 field: VirobnikId
177 alias: g.VirobnikId 178 alias: g.VirobnikId
178 caption: VirobnikId 179 caption: VirobnikId
179 width: 200 180 width: 200
180 readonly: true 181 readonly: true
181 hidden: true 182 hidden: true
182 type_field: text 183 type_field: text
183 184
184 agronomid: 185 agronomid:
185 field: fio 186 field: fio
186 alias: a.fio 187 alias: a.fio
187 caption: ПІБ агронома-інспектора 188 caption: ПІБ агронома-інспектора
188 width: 75 189 width: 75
189 readonly: false 190 readonly: false
190 hidden: false 191 hidden: false
191 align: left 192 align: left
192 width_form: 220 193 width_form: 220
193 alias_form: agronomid 194 alias_form: agronomid
194 formoptions: 195 formoptions:
195 rowpos: 5 196 rowpos: 5
196 colpos: 2 197 colpos: 2
197 type_fieldform: DropDown 198 type_fieldform: DropDown
198 sql_form: select auditid as k, fio as v from dp2_auditors 199 sql_form: select auditid as k, fio as v from dp2_auditors
199 main_filter: true 200 main_filter: true
200 type_field: text 201 type_field: text
201 202
202 cultid: 203 cultid:
203 field: Kultura 204 field: Kultura
204 alias: k.Kultura 205 alias: k.Kultura
205 caption: Культура 206 caption: Культура
206 depend: sortid 207 depend: sortid
207 depend_sql: 'select SortID as k, NameUA as v from dp2SortReestr where CodKult = {mid} ' 208 depend_sql: 'select SortID as k, NameUA as v from dp2SortReestr where CodKult = {mid} '
208 width: 150 209 width: 150
209 readonly: false 210 readonly: false
210 required: true 211 required: true
211 align: left 212 align: left
212 formoptions: 213 formoptions:
213 rowpos: 7 214 rowpos: 7
214 colpos: 0 215 colpos: 0
215 width_form: 220 216 width_form: 220
216 additems: 217 additems:
217 '': --------------- 218 '': ---------------
218 alias_form: cultid 219 alias_form: cultid
219 type_fieldform: DropDown 220 type_fieldform: DropDown
220 sql_form: select CodKult as k, Kultura as v from dp2Kultur order by Kultura 221 sql_form: select CodKult as k, Kultura as v from dp2Kultur order by Kultura
221 main_filter: true 222 main_filter: true
222 type_field: text 223 type_field: text
223 224
224 sortid: 225 sortid:
225 field: NameUA 226 field: NameUA
226 alias: s.NameUA 227 alias: s.NameUA
227 caption: Сорт 228 caption: Сорт
228 width: 75 229 width: 75
229 readonly: false 230 readonly: false
230 align: left 231 align: left
231 type_fieldform: DropDown 232 type_fieldform: DropDown
232 alias_form: sortid 233 alias_form: sortid
233 sql_form: select SortID as k, NameUA as v from dp2SortReestr order by NameUA 234 sql_form: select SortID as k, NameUA as v from dp2SortReestr order by NameUA
234 formoptions: 235 formoptions:
235 rowpos: 7 236 rowpos: 7
236 colpos: 2 237 colpos: 2
237 additems: 238 additems:
238 '': --------------- 239 '': ---------------
239 child: true 240 child: true
240 width_form: 220 241 width_form: 220
241 main_filter: true 242 main_filter: true
242 type_field: text 243 type_field: text
243 244
244 catid: 245 catid:
245 field: cat_name 246 field: cat_name
246 alias: c.cat_name 247 alias: c.cat_name
247 caption: Категорія 248 caption: Категорія
248 width: 100 249 width: 100
249 readonly: false 250 readonly: false
250 required: true 251 required: true
251 align: left 252 align: left
252 formoptions: 253 formoptions:
253 rowpos: 10 254 rowpos: 10
254 colpos: 0 255 colpos: 0
255 width_form: 220 256 width_form: 220
256 alias_form: catid 257 alias_form: catid
257 additems: 258 additems:
258 '': --------------- 259 '': ---------------
259 type_fieldform: DropDown 260 type_fieldform: DropDown
260 sql_form: select catid as k, cat_name as v from dp2Categors order by active desc 261 sql_form: select catid as k, cat_name as v from dp2Categors order by active desc
261 main_filter: true 262 main_filter: true
262 type_field: text 263 type_field: text
263 264
264 genid: 265 genid:
265 field: generation_name 266 field: generation_name
266 alias: ge.generation_name 267 alias: ge.generation_name
267 caption: Генерація, що</br>сертифікується 268 caption: Генерація, що</br>сертифікується
268 width: 100 269 width: 100
269 readonly: false 270 readonly: false
270 # required: true 271 # required: true
271 align: left 272 align: left
272 alias_form: genid 273 alias_form: genid
273 formoptions: 274 formoptions:
274 rowpos: 10 275 rowpos: 10
275 colpos: 2 276 colpos: 2
276 width_form: 220 277 width_form: 220
277 additems: 278 additems:
278 '': --------------- 279 '': ---------------
279 type_fieldform: DropDown 280 type_fieldform: DropDown
280 sql_form: select generationid as k, generation_name as v from dp2generation order by active desc 281 sql_form: select generationid as k, generation_name as v from dp2generation order by active desc
281 main_filter: true 282 main_filter: true
282 type_field: text 283 type_field: text
283 284
284 actnum: 285 actnum:
285 field: actnum 286 field: actnum
286 caption: № Акт відбору 287 caption: № Акт відбору
287 alias: g.actnum 288 alias: g.actnum
288 width: 100 289 width: 100
289 readonly: false 290 readonly: false
290 align: left 291 align: left
291 width_form: 220 292 width_form: 220
292 type_field: text 293 type_field: text
293 formoptions: 294 formoptions:
294 rowpos: 12 295 rowpos: 12
295 colpos: 0 296 colpos: 0
296 297
297 actdate: 298 actdate:
298 field: actdate 299 field: actdate
299 caption: Дата акту відбору 300 caption: Дата акту відбору
300 alias: g.actdate 301 alias: g.actdate
301 width: 100 302 width: 100
302 readonly: false 303 readonly: false
303 align: left 304 align: left
304 width_form: 200 305 width_form: 200
305 type_field: date 306 type_field: date
306 formoptions: 307 formoptions:
307 rowpos: 12 308 rowpos: 12
308 colpos: 2 309 colpos: 2
309 310
310 partnum: 311 partnum:
311 field: partnum 312 field: partnum
312 caption: Номер партії 313 caption: Номер партії
313 alias: g.partnum 314 alias: g.partnum
314 width: 150 315 width: 150
315 readonly: false 316 readonly: false
316 align: left 317 align: left
317 width_form: 220 318 width_form: 220
318 formoptions: 319 formoptions:
319 rowpos: 13 320 rowpos: 13
320 colpos: 0 321 colpos: 0
321 adds_class: brd_btm 322 adds_class: brd_btm
322 type_field: text 323 type_field: text
323 324
324 mass_part: 325 mass_part:
325 field: mass_part 326 field: mass_part
326 caption: Маса партії 327 caption: Маса партії
327 alias: g.mass_part 328 alias: g.mass_part
328 width: 150 329 width: 150
329 readonly: true 330 readonly: true
330 align: left 331 align: left
331 type_field: text 332 type_field: text
332 333
333 posada: 334 posada:
334 field: dp_posad_name 335 field: dp_posad_name
335 caption: Посада 336 caption: Посада
336 alias: a.dp_posad_name 337 alias: a.dp_posad_name
337 width: 150 338 width: 150
338 readonly: true 339 readonly: true
339 align: left 340 align: left
340 type_field: text 341 type_field: text
341 342
342 vidpravlenoid: 343 vidpravlenoid:
343 field: vname 344 field: vname
344 alias: v.name 345 alias: v.name
345 caption: Відправлено зразок 346 caption: Відправлено зразок
346 width: 75 347 width: 75
347 readonly: false 348 readonly: false
348 hidden: false 349 hidden: false
349 align: left 350 align: left
350 width_form: 220 351 width_form: 220
351 alias_form: vidpravlenoid 352 alias_form: vidpravlenoid
352 additems: 353 additems:
353 '': --------------- 354 '': ---------------
354 formoptions: 355 formoptions:
355 rowpos: 13 356 rowpos: 13
356 colpos: 2 357 colpos: 2
357 type_fieldform: DropDown 358 type_fieldform: DropDown
358 sql_form: select vidpravlenoid as k, name as v from dp2_grunt_vidprav 359 sql_form: select vidpravlenoid as k, name as v from dp2_grunt_vidprav
359 adds_class: brd_btm 360 adds_class: brd_btm
360 type_field: text 361 type_field: text
361 362
362 dogstatusid: 363 dogstatusid:
363 field: statusname 364 field: statusname
364 alias: ds.statusname 365 alias: ds.statusname
365 caption: Договір <br>проект/укладено 366 caption: Договір <br>проект/укладено
366 width: 100 367 width: 100
367 readonly: false 368 readonly: false
368 hidden: false 369 hidden: false
369 align: left 370 align: left
370 width_form: 220 371 width_form: 220
371 alias_form: dogstatusid 372 alias_form: dogstatusid
372 additems: 373 additems:
373 '': --------------- 374 '': ---------------
374 formoptions: 375 formoptions:
375 rowpos: 30 376 rowpos: 30
376 colpos: 2 377 colpos: 2
377 type_fieldform: DropDown 378 type_fieldform: DropDown
378 sql_form: select dogstatusid as k, statusname as v from dp2_grunt_dogstatus 379 sql_form: select dogstatusid as k, statusname as v from dp2_grunt_dogstatus
379 type_field: text 380 type_field: text
380 381
381 oplataid: 382 oplataid:
382 field: oname 383 field: oname
383 alias: o.name 384 alias: o.name
384 caption: Оплата 385 caption: Оплата
385 width: 75 386 width: 75
386 readonly: false 387 readonly: false
387 hidden: false 388 hidden: false
388 align: left 389 align: left
389 width_form: 220 390 width_form: 220
390 alias_form: oplataid 391 alias_form: oplataid
391 additems: 392 additems:
392 '': --------------- 393 '': ---------------
393 formoptions: 394 formoptions:
394 rowpos: 40 395 rowpos: 40
395 colpos: 2 396 colpos: 2
396 type_fieldform: DropDown 397 type_fieldform: DropDown
397 sql_form: select oplataid as k, name as v from dp2_grunt_oplat 398 sql_form: select oplataid as k, name as v from dp2_grunt_oplat
398 type_field: text 399 type_field: text
399 400
400 factnadhid: 401 factnadhid:
401 field: fnname 402 field: fnname
402 alias: fn.name 403 alias: fn.name
403 caption: Фактичне надходження<br>зразка/Акту відбору 404 caption: Фактичне надходження<br>зразка/Акту відбору
404 width: 75 405 width: 75
405 readonly: false 406 readonly: false
406 hidden: false 407 hidden: false
407 align: left 408 align: left
408 width_form: 220 409 width_form: 220
409 alias_form: factnadhid 410 alias_form: factnadhid
410 additems: 411 additems:
411 '': --------------- 412 '': ---------------
412 formoptions: 413 formoptions:
413 rowpos: 30 414 rowpos: 30
414 colpos: 0 415 colpos: 0
415 type_fieldform: DropDown 416 type_fieldform: DropDown
416 sql_form: select factnadhid as k, name as v from dp2_grunt_factnadh 417 sql_form: select factnadhid as k, name as v from dp2_grunt_factnadh
417 type_field: text 418 type_field: text
418 419
419 zvitnum: 420 zvitnum:
420 field: zvitnum 421 field: zvitnum
421 caption: № Звіту 422 caption: № Звіту
422 alias: zvitnum 423 alias: zvitnum
423 width: 100 424 width: 100
424 readonly: false 425 readonly: false
425 align: left 426 align: left
426 width_form: 220 427 width_form: 220
427 type_field: text 428 type_field: text
428 formoptions: 429 formoptions:
429 rowpos: 34 430 rowpos: 34
430 colpos: 0 431 colpos: 0
431 432
432 zvitdate: 433 zvitdate:
433 field: zvitdate 434 field: zvitdate
434 caption: Дата звіту 435 caption: Дата звіту
435 alias: g.zvitdate 436 alias: g.zvitdate
436 width: 100 437 width: 100
437 readonly: false 438 readonly: false
438 align: left 439 align: left
439 width_form: 198 440 width_form: 198
440 type_field: date 441 type_field: date
441 formoptions: 442 formoptions:
442 rowpos: 34 443 rowpos: 34
443 colpos: 2 444 colpos: 2
444 sortchyst: 445 sortchyst:
445 field: sortchyst 446 field: sortchyst
446 caption: Сортова <br>чистота, % 447 caption: Сортова <br>чистота, %
447 alias: g.sortchyst 448 alias: g.sortchyst
448 width: 75 449 width: 75
449 readonly: false 450 readonly: false
450 align: right 451 align: right
451 type_field: text 452 type_field: text
452 formoptions: 453 formoptions:
453 rowpos: 40 454 rowpos: 40
454 colpos: 0 455 colpos: 0
455 456
456 usercreate: 457 usercreate:
457 field: uclogin 458 field: uclogin
458 alias: g.usercreate 459 alias: g.usercreate
459 alias_form: uclogin 460 alias_form: uclogin
460 caption: Створив 461 caption: Створив
461 width: 75 462 width: 75
462 readonly: true 463 readonly: true
463 disabled: true 464 disabled: true
464 is_change: true 465 is_change: true
465 align: left 466 align: left
466 width_form: 150 467 width_form: 150
467 hidden_form: true 468 hidden_form: true
468 type_field: text 469 type_field: text
469 470
470 datecreate: 471 datecreate:
471 field: datecreate 472 field: datecreate
472 alias: g.datecreate 473 alias: g.datecreate
473 caption: Коли створив 474 caption: Коли створив
474 width: 100 475 width: 100
475 readonly: true 476 readonly: true
476 Акdisabled: true 477 Акdisabled: true
477 width_form: 150 478 width_form: 150
478 type_field: datetime 479 type_field: datetime
479 hidden_form: true 480 hidden_form: true
480 481
481 userupdate: 482 userupdate:
482 field: uulogin 483 field: uulogin
483 alias: g.userupdate 484 alias: g.userupdate
484 alias_form: uulogin 485 alias_form: uulogin
485 caption: Змінив 486 caption: Змінив
486 width: 75 487 width: 75
487 readonly: false 488 readonly: false
488 is_change: true 489 is_change: true
489 align: left 490 align: left
490 def_value: <%USERID%> 491 def_value: <%USERID%>
491 width_form: 150 492 width_form: 150
492 hidden_form: true 493 hidden_form: true
493 type_field: text 494 type_field: text
494 495
495 dateupdate: 496 dateupdate:
496 field: dateupdate 497 field: dateupdate
497 alias: g.dateupdate 498 alias: g.dateupdate
498 caption: Коли змінено 499 caption: Коли змінено
499 width: 100 500 width: 100
500 readonly: false 501 readonly: false
501 disabled: true 502 disabled: true
502 is_change: true 503 is_change: true
503 def_value: <%Now%> 504 def_value: <%Now%>
504 # formoptions: 505 # formoptions:
505 # rowpos: 46 506 # rowpos: 46
506 # colpos: 2 507 # colpos: 2
507 width_form: 150 508 width_form: 150
508 type_field: datetime 509 type_field: datetime
509 hidden_form: true 510 hidden_form: true
510 511
511 detail_field: 512 detail_field:
512 fileid: 513 fileid:
513 field: fileid 514 field: fileid
514 caption: ID 515 caption: ID
515 516
516 gruntcontrolid: 517 gruntcontrolid:
517 field: gruntcontrolid 518 field: gruntcontrolid
518 caption: Зовнішній ключ з Грунтконтроль 519 caption: Зовнішній ключ з Грунтконтроль
519 520
520 filename: 521 filename:
521 field: file_name 522 field: file_name
522 caption: Назва файлу 523 caption: Назва файлу
523 524
524 usercreate: 525 usercreate:
525 field: usercreate 526 field: usercreate
526 caption: Створив 527 caption: Створив
527 528
1 select: 1 select:
2 select roleid, rolename, commentrole, active, pubrole, order_roles, is_admin, classrole 2 select roleid, rolename, commentrole, active, pubrole, order_roles, is_admin, classrole
3 from k2roles 3 from k2roles
4 table: k2roles 4 table: k2roles
5 sortname: order_roles 5 sortname: order_roles
6 typeid: 1 6 typeid: 1
7 sortorder: asc 7 sortorder: asc
8 caption: <%lnRights%> 8 caption: <%lnRights%>
9 fields: 9 fields:
10 roleid: 10 roleid:
11 field: roleid 11 field: roleid
12 caption: ID 12 caption: ID
13 width: 40 13 width: 40
14 readonly: true 14 readonly: true
15 align: left 15 align: left
16 hidden: true 16 hidden: true
17 type_field: text
18 primary_key: true
17 19
18 rolename: 20 rolename:
19 field: rolename 21 field: rolename
20 caption: Назва ролі 22 caption: Назва ролі
21 width: 250 23 width: 250
22 readonly: false 24 readonly: false
23 align: left 25 align: left
26 type_field: text
24 27
25 order_roles: 28 order_roles:
26 field: order_roles 29 field: order_roles
27 caption: Сортування 30 caption: Сортування
28 width: 100 31 width: 100
29 readonly: false 32 readonly: false
30 align: right 33 align: right
34 type_field: text
31 35
32 commentrole: 36 commentrole:
33 field: commentrole 37 field: commentrole
34 caption: Примітка 38 caption: Примітка
35 width: 150 39 width: 150
36 readonly: false, 40 readonly: false,
37 align: left 41 align: left
38 42 type_field: text
39 43
40 active: 44 active:
41 field: active 45 field: active
42 caption: Активність 46 caption: Активність
43 width: 100 47 width: 100
44 readonly: false 48 readonly: false
45 align: center 49 align: center
46 type_field: checkbox 50 type_field: checkbox
47 def_value: 1 51 def_value: 1
48 52
49 # 5: 53 # 5:
50 # field: pubrole 54 # field: pubrole
51 # caption: <%lnPublic%> 55 # caption: <%lnPublic%>
52 # width: 100 56 # width: 100
53 # readonly: false 57 # readonly: false
54 # align: center 58 # align: center
55 # type_field: checkbox 59 # type_field: checkbox
56 # def_value: 1 60 # def_value: 1
57 61
58 classrole: 62 classrole:
59 field: classrole 63 field: classrole
60 caption: Стороння роль 64 caption: Стороння роль
61 width: 100 65 width: 100
62 readonly: false 66 readonly: false
63 align: center 67 align: center
64 type_field: checkbox 68 type_field: checkbox
65 def_value: 1 69 def_value: 1
66 70
67 is_admin: 71 is_admin:
68 field: is_admin 72 field: is_admin
69 caption: Доступ до адмін 73 caption: Доступ до адмін
70 width: 100 74 width: 100
71 readonly: false 75 readonly: false
72 align: center 76 align: center
73 type_field: checkbox 77 type_field: checkbox
74 def_value: 1 78 def_value: 1
75 79
1 select: 1 select:
2 select u.user_id, u.name, u.login, u.password, u.email, u.phone, u.photo, u.firstname, u.middlename, 2 select u.user_id, u.name, u.login, u.password, u.email, u.phone, u.photo, u.firstname, u.middlename,
3 u.lastname, u.roleid, u.create_datetime, u.who_create, u.firmid, u.partner_transid, u.departmentid, u.tab_number, u.name_rod, u.posada_rod, 3 u.lastname, u.roleid, u.create_datetime, u.who_create, u.firmid, u.partner_transid, u.departmentid, u.tab_number, u.name_rod, u.posada_rod,
4 u.all_obl, u.order_ins, u.prover, u.active, u.birth_date, f.name_firm, f.edrpou, r.rolename, r.classrole, d.department_name, u.passwd_decode 4 u.all_obl, u.order_ins, u.prover, u.active, u.birth_date, f.name_firm, f.edrpou, r.rolename, r.classrole, d.department_name, u.passwd_decode
5 from k2users u 5 from k2users u
6 6
7 left join k2firms f 7 left join k2firms f
8 on u.firmid=f.firmid 8 on u.firmid=f.firmid
9 9
10 left join k2roles r 10 left join k2roles r
11 on u.roleid=r.roleid 11 on u.roleid=r.roleid
12 12
13 left join k2department d 13 left join k2department d
14 on u.departmentid=d.departmentid 14 on u.departmentid=d.departmentid
15 15
16 table: k2users 16 table: k2users
17 typeid: 1 17 typeid: 1
18 rows: 20 18 rows: 20
19 sortname: create_datetime 19 sortname: create_datetime
20 sortorder: desc 20 sortorder: desc
21 detile: k2users_obl
22 caption: <%lnUsers%> 21 caption: <%lnUsers%>
23 readonly_form: 22 readonly_form:
24 who_create: 23 who_create:
25 height: 550 24 height: 550
26 form_height: 325 25 form_height: 325
27 custom_form: true 26 custom_form: true
28 27
29 fields: 28 fields:
30 user_id: 29 user_id:
31 field: user_id 30 field: user_id
32 caption: ID 31 caption: ID
32 alias: u.user_id
33 width: 40 33 width: 40
34 readonly: true 34 readonly: true
35 align: left 35 align: left
36 hidden: true 36 hidden: true
37 type_field: text
38 primary_key: true
37 39
38 order_ins: 40 order_ins:
39 field: order_ins 41 field: order_ins
42 alias: u.order_ins
40 caption: № 43 caption: №
41 width: 40 44 width: 40
42 readonly: true 45 readonly: true
43 align: left 46 align: left
44 hidden: true 47 hidden: true
45 48 type_field: text
46 49
47
48 login: 50 login:
49 field: login 51 field: login
50 caption: Email 52 caption: Email
53 alias: u.login
51 width: 100 54 width: 100
52 width_form: 250 55 width_form: 250
53 readonly: false 56 readonly: false
54 align: left 57 align: left
58 type_field: text
55 59
56 act: 60 act:
57 field: " " 61 field: " "
58 alias: u.active 62 alias: u.active
59 caption: Акт. 63 caption: Акт.
60 width: 95 64 width: 95
61 readonly: true 65 readonly: true
62 align: center 66 align: center
63 type_field: condition 67 type_field: condition
64 cond: 68 cond:
65 exp: ($row["active"]==0) 69 exp: ($row["active"]==0)
66 url1: "" 70 url1: ""
67 target1: _self 71 target1: _self
68 target2: _self 72 target2: _self
69 caption1: <button style="color:red" onclick="doAkt('{user_id}')">Активувати</button> 73 caption1: <button style="color:red" onclick="doAkt('{user_id}')">Активувати</button>
70 url2: "" 74 url2: ""
71 caption2: <button onclick="doAkt('{user_id}')">Вимкнути</button> 75 caption2: <button onclick="doAkt('{user_id}')">Вимкнути</button>
72 76
73 2: 77 2:
74 field: " " 78 field: " "
75 caption: Зміна пароля 79 caption: Зміна пароля
76 width: 110 80 width: 110
77 readonly: true 81 readonly: true
78 align: center 82 align: center
79 type_field: condition 83 type_field: condition
80 cond: 84 cond:
81 exp: (false) 85 exp: (false)
82 url2: "/?adm=k2adminfunc_changepassword&userid={login}&mode=admin" 86 url2: "/?adm=k2adminfunc_changepassword&userid={login}&mode=admin"
83 caption2: "Змінити" 87 caption2: "Змінити"
84 88
85 89
86 name: 90 name:
87 field: name 91 field: name
92 alias: u.name
88 caption: Ім'я 93 caption: Ім'я
89 width: 250 94 width: 250
90 readonly: false 95 readonly: false
91 align: left 96 align: left
97 type_field: text
92 98
93 birth_date: 99 birth_date:
94 field: birth_date 100 field: birth_date
101 alias: u.birth_date
95 caption: Дата<br>народження 102 caption: Дата<br>народження
96 width: 100 103 width: 100
97 width_form: 250 104 width_form: 250
98 readonly: false 105 readonly: false
99 align: left 106 align: left
100 type_field: date 107 type_field: date
101 108
102 email: 109 email:
103 field: email 110 field: email
104 alias: u.email 111 alias: u.email
105 caption: Електронна пошта 112 caption: Електронна пошта
106 width: 175 113 width: 175
107 width_form: 250 114 width_form: 250
108 readonly: false 115 readonly: false
109 align: left 116 align: left
117 type_field: text
110 118
111 phone: 119 phone:
112 field: phone 120 field: phone
121 alias: u.phone
113 caption: Номер 122 caption: Номер
114 width: 100 123 width: 100
115 width_form: 250 124 width_form: 250
116 readonly: false 125 readonly: false
117 align: left 126 align: left
127 type_field: text
118 128
119 tab_number: 129 tab_number:
120 field: tab_number 130 field: tab_number
131 alias: u.tab_number
121 caption: Таб. номер 132 caption: Таб. номер
122 width: 75 133 width: 75
123 width_form: 250 134 width_form: 250
124 readonly: false 135 readonly: false
125 align: left 136 align: left
137 type_field: text
126 138
127 139
128 rolename: 140 rolename:
129 field: rolename 141 field: rolename
130 alias: r.rolename 142 alias: r.rolename
131 caption: Права 143 caption: Права
132 width: 150 144 width: 150
133 width_form: 250 145 width_form: 250
134 readonly: false 146 readonly: false
147 type_field: text
135 align: left 148 align: left
136 # type_field: DropDown 149 # type_field: DropDown
137 multy: false 150 multy: false
138 # sql: "select roleid as k, rolename as v from k2roles where (active='1') order by rolename" 151 # sql: "select roleid as k, rolename as v from k2roles where (active='1') order by rolename"
139 type_fieldform: DropDown 152 type_fieldform: DropDown
140 alias_form: roleid 153 alias_form: roleid
141 sql_form: select roleid as k, rolename as v from k2roles where (active='1') order by rolename 154 sql_form: select roleid as k, rolename as v from k2roles where (active='1') order by rolename
142 155
143 roleid: 156 roleid:
144 field: roleid 157 field: roleid
158 alias: u.roleid
145 caption: 159 caption:
146 width: 150 160 width: 150
147 readonly: true 161 readonly: true
148 hidden: true 162 hidden: true
163 type_field: text
149 164
150 department_name: 165 department_name:
151 field: department_name 166 field: department_name
152 alias: d.department_name 167 alias: d.department_name
153 caption: Підрозділ 168 caption: Підрозділ
154 width: 150 169 width: 150
155 width_form: 250 170 width_form: 250
156 readonly: false 171 readonly: false
172 type_field: text
157 align: left 173 align: left
158 # type_field: DropDown 174 # type_field: DropDown
159 multy: false 175 multy: false
160 # sql: "select roleid as k, rolename as v from k2roles where (active='1') order by rolename" 176 # sql: "select roleid as k, rolename as v from k2roles where (active='1') order by rolename"
161 type_fieldform: DropDown 177 type_fieldform: DropDown
162 alias_form: departmentid 178 alias_form: departmentid
163 additems: 179 additems:
164 '': --------------- 180 '': ---------------
165 sql_form: select departmentid as k, department_name as v from k2department 181 sql_form: select departmentid as k, department_name as v from k2department
166 182
167 departmentid: 183 departmentid:
168 field: departmentid 184 field: departmentid
185 alias: u.departmentid
169 caption: 186 caption:
170 width: 150 187 width: 150
171 readonly: true 188 readonly: true
172 hidden: true 189 hidden: true
190 type_field: text
173 191