Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: jans-cli-tui #3287

Merged
merged 30 commits into from
Jan 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
341d975
fix(jans-cli-tui) fix Empty spaces in multi tab properties ref:(#3286)
AbdelwahabAdam Dec 12, 2022
94c7d42
fix: jans-cli-tui save script location
devrimyatar Dec 12, 2022
a5c51ef
fix: jans-linux-tui remove updatedAt from user edit
devrimyatar Dec 13, 2022
b31307b
fix: jans-cli-tui user-edit None value
devrimyatar Dec 13, 2022
d945c9e
fix:jans-cli-tui rename jans_date_picker
AbdelwahabAdam Dec 14, 2022
cdc8ad6
fix:jans-cli-tui refactor test files for renaming jans_date_picker
AbdelwahabAdam Dec 14, 2022
3e29868
fix:jans-cli-tui fix import error
AbdelwahabAdam Dec 17, 2022
e599ea2
feat:jans-cli-tui add mouse menu for cut, paste, copy (ref: #2712)
AbdelwahabAdam Dec 19, 2022
d5e60dc
fix:jans-cli-tui remove unused imports
AbdelwahabAdam Dec 19, 2022
5c8e03d
fix:jans-cli-tui change user password (ref: #3360)
AbdelwahabAdam Dec 20, 2022
9978479
fix: jans-cli-tui imports
devrimyatar Dec 21, 2022
86eedd6
Revert "fix: jans-cli-tui imports"
devrimyatar Dec 21, 2022
ecf15b2
fix: jans-cli-tui imports
devrimyatar Dec 21, 2022
d143b01
feat: jans-cli-tui option --no-tui
devrimyatar Dec 21, 2022
e8bb14f
fix:jans-cli-tui unable to search user in search box (ref: #3353)
AbdelwahabAdam Dec 21, 2022
d68a13b
fix: jans-cli-tui searches should call <get>if no search string enter…
AbdelwahabAdam Dec 21, 2022
1bf0aff
fix:jans-cli-tui reverting changes for worng user password implementa…
AbdelwahabAdam Dec 21, 2022
456ae85
fix: jans-cli-tui user patch operation
devrimyatar Dec 23, 2022
d5716c2
fix: rename 010_oxauth as 010_auth_server
devrimyatar Dec 23, 2022
4c2775c
fix: rename oxauth to_oauth
devrimyatar Dec 23, 2022
7bd8d26
fix: jans-cli-tui parse escaped colon for patch (ref: #3448)
devrimyatar Dec 29, 2022
75d2e1c
fix: jans-cli-tui fix typo (ref: #3475)
AbdelwahabAdam Dec 31, 2022
c4e5ddf
fix:jans-cli-tui fix script search (ref #3468)
AbdelwahabAdam Dec 31, 2022
5439c07
fix:jans-cli-tui fix script search (ref #3468)
AbdelwahabAdam Dec 31, 2022
5b0ecff
fix: jan-cli-tui add none option to tokenEndpointAuthMethod (ref: #3463)
devrimyatar Dec 31, 2022
fbaa227
fix: jans-cli-tui code smells
devrimyatar Jan 2, 2023
90fe169
fix: jans-cli-tui code smells
devrimyatar Jan 2, 2023
456f6cf
fix: jans-cli-tui code smells
devrimyatar Jan 2, 2023
76f2453
fix: jans-cli-tui code smells
devrimyatar Jan 2, 2023
9d2dfd7
fix: jans-cli-tui typo
devrimyatar Jan 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions jans-cli-tui/cli_tui/cli/config_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,11 @@ def patch_requests(self, endpoint, url_param_dict, data):
security = self.get_scope_for_endpoint(endpoint)
self.get_access_token(security)

headers = self.get_request_header({'Accept': 'application/json', 'Content-Type': 'application/json-patch+json'})
content_key = 'application/json-patch+json'
for content_key in endpoint.info.get('requestBody', {}).get('content', {}):
break

headers = self.get_request_header({'Accept': 'application/json', 'Content-Type': content_key})
data = data
response = requests.patch(
url=url,
Expand Down Expand Up @@ -1361,17 +1365,18 @@ def process_command_patch(self, path, suffix_param, endpoint_params, data_fn, da
except ValueError as ve:
self.exit_with_error(str(ve))

if not isinstance(data, list):
if ('configuser' not in endpoint.path) and (not isinstance(data, list)):
self.exit_with_error("{} must be array of /components/schemas/PatchRequest".format(data_fn))

op_modes = ('add', 'remove', 'replace', 'move', 'copy', 'test')
if 'configuser' not in endpoint.path:
op_modes = ('add', 'remove', 'replace', 'move', 'copy', 'test')

for item in data:
if not item['op'] in op_modes:
print("op must be one of {}".format(', '.join(op_modes)))
sys.exit()
if not item['path'].startswith('/'):
item['path'] = '/' + item['path']
for item in data:
if not item['op'] in op_modes:
print("op must be one of {}".format(', '.join(op_modes)))
sys.exit()
if not item['path'].startswith('/'):
item['path'] = '/' + item['path']

response = self.patch_requests(endpoint, suffix_param, data)

Expand Down Expand Up @@ -1419,11 +1424,13 @@ def process_command_by_id(self, operation_id, url_suffix, endpoint_args, data_fn
pdata = args.patch_replace

if pop:
if pop != 'remove' and pdata.count(':') != 1:
self.exit_with_error("Please provide --patch-data as colon delimited key:value pair")
if pop != 'remove':
try:
ppath, pval = self.unescaped_split(pdata, ':')
except Exception:
self.exit_with_error("Please provide --patch-data as colon delimited key:value pair.\nUse escape if you need colon in value or key, i.e. mtlsUserInfoEndpoint:https\\:example.jans.io/userinfo")

if pop != 'remove':
ppath, pval = pdata.split(':')
data = [{'op': pop, 'path': '/'+ ppath.lstrip('/'), 'value': pval}]
else:
data = [{'op': pop, 'path': '/'+ pdata.lstrip('/')}]
Expand Down
18 changes: 18 additions & 0 deletions jans-cli-tui/cli_tui/cli_style.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@

"outh-titledtext":"green",
"outh-label":"blue",

# PLUGINS
"plugin-navbar":"#2600ff",
"plugin-navbar-headcolor":"green",
"plugin-navbar-entriescolor":"blue",
"plugin-tabs":"",
"plugin-text":"green",
"plugin-textsearch":"",
"plugin-label":"bold",
"plugin-textrequired":"#8b000a",
"plugin-checkbox":"green",
"plugin-checkboxlist":"green",
"plugin-radiobutton":"green",
"plugin-dropdown":"green",
"plugin-widget":"green",
"plugin-container":"",
"plugin-container.text":"green",

## edit_client_dialog
"outh-client-navbar":"#2600ff",
"outh-client-navbar-headcolor":"green",
Expand Down
191 changes: 181 additions & 10 deletions jans-cli-tui/cli_tui/jans_cli_tui.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@
if os.path.exists(pylib_dir):
sys.path.insert(0, pylib_dir)

no_tui = False
if '--no-tui' in sys.argv:
sys.argv.remove('--no-tui')
no_tui = True

from cli import config_cli

if no_tui:
config_cli.main()
sys.exit()

import prompt_toolkit
from prompt_toolkit.application import Application
from prompt_toolkit.application.current import get_app
Expand Down Expand Up @@ -63,19 +74,16 @@
from typing import TypeVar, Callable
from prompt_toolkit.widgets import Button, Dialog, Label

# -------------------------------------------------------------------------- #
from cli import config_cli
from utils.validators import IntegerValidator
from wui_components.jans_cli_dialog import JansGDialog
from wui_components.jans_nav_bar import JansNavBar
from wui_components.jans_message_dialog import JansMessageDialog

from cli_style import style

import cli_style

from utils.multi_lang import _
# -------------------------------------------------------------------------- #
from prompt_toolkit.mouse_events import MouseEvent, MouseEventType
from prompt_toolkit.keys import Keys


home_dir = Path.home()
config_dir = home_dir.joinpath('.config')
Expand Down Expand Up @@ -109,6 +117,7 @@ def __init__(self):
self.cli_object_ok = False
self.pbar_text = ""
self.progressing_text = ""
self.mouse_float=True

self.not_implemented = Frame(
body=HSplit([Label(text=_("Not imlemented yet")), Button(text=_("MyButton"))], width=D()),
Expand Down Expand Up @@ -290,7 +299,7 @@ async def coroutine():
await self.show_dialog_as_float(dialog)
try:
app.layout.focus(focused_before)
except:
except Exception:
app.layout.focus(self.center_frame)

self.start_progressing()
Expand Down Expand Up @@ -364,7 +373,7 @@ async def coroutine():
result = await self.show_dialog_as_float(dialog)
try:
app.layout.focus(focused_before)
except:
except Exception:
app.layout.focus(self.center_frame)

self.create_cli()
Expand All @@ -380,6 +389,167 @@ def set_keybindings(self) -> None:
self.bindings.add('f1')(self.help)
self.bindings.add('escape')(self.escape)
self.bindings.add('s-up')(self.up)
self.bindings.add(Keys.Vt100MouseEvent)(self.mouse)



def mouse(self,event): ### mouse: [<35;108;20M

pieces = event.data.split(";") ##['LEFT', 'MOUSE_DOWN', '146', '10']
mouse_click=int(pieces[0][3:])
mouse_state=str(pieces[2][-1:])
x = int(pieces[1])
y = int(pieces[2][:-1])

mouse_event, x, y = map(int, [mouse_click,x,y])
m = mouse_state

mouse_event = {
(0, 'M'): MouseEventType.MOUSE_DOWN,
(0, 'm'): MouseEventType.MOUSE_UP,
(2, 'M'): MouseEventType.MOUSE_DOWN,
(2, 'm'): MouseEventType.MOUSE_UP,
(64, 'M'): MouseEventType.SCROLL_UP,
(65, 'M'): MouseEventType.SCROLL_DOWN,
}.get((mouse_event, m))

mouse_click = {
0: "LEFT",
2: "RIGHT"
}.get(mouse_click)


# ------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------ #
style_tmp = '<style >{}</style>'
style_tmp_red = '<style fg="ansired" bg="#00FF00">{}</style>'

res=[]
res.append(HTML(style_tmp.format("Copy")))
res.append("\n")
res.append(HTML(style_tmp.format("Cut")))
res.append("\n")
res.append(HTML(style_tmp.format("Paste")))
res.append("\n")

content= Window(
content=FormattedTextControl(
text=merge_formatted_text(res),
focusable=True,
), height=D())
floa=Float(content=content, left=x,top=y)
floa.name='mouse'

# ------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------ #

if mouse_click == "RIGHT" and mouse_event == MouseEventType.MOUSE_DOWN :
if self.mouse_float == True :
self.root_layout.floats.append(floa)
self.mouse_cord=(x,y)
self.mouse_float = False
else:
try:
if get_app().layout.container.floats:
if get_app().layout.container.floats[-1].name =='mouse':
get_app().layout.container.floats.remove(get_app().layout.container.floats[-1])
self.root_layout.floats.append(floa)
self.mouse_cord=(x,y)
self.mouse_float = False
else:
self.root_layout.floats.append(floa)
self.mouse_cord=(x,y)
self.mouse_float = False
else:
self.root_layout.floats.append(floa)
self.mouse_cord=(x,y)
self.mouse_float = False
except Exception:
pass

elif mouse_click == "LEFT" and mouse_event == MouseEventType.MOUSE_DOWN and self.mouse_float == False:
try:
if get_app().layout.container.floats:
if get_app().layout.container.floats[-1].name =='mouse':

if self.mouse_select =='Copy':
data = get_app().current_buffer.copy_selection(False)
get_app().clipboard.set_data(data)
get_app().layout.container.floats.remove(get_app().layout.container.floats[-1])
self.mouse_float = True

elif self.mouse_select =='Paste':
data = get_app().clipboard.get_data()
get_app().current_buffer.paste_clipboard_data(data)
get_app().layout.container.floats.remove(get_app().layout.container.floats[-1])
self.mouse_float = True

elif self.mouse_select =='Cut':
data = get_app().current_buffer.copy_selection(True)
get_app().clipboard.set_data(data)
get_app().layout.container.floats.remove(get_app().layout.container.floats[-1])
self.mouse_float = True

else:
get_app().layout.container.floats.remove(get_app().layout.container.floats[-1])
self.mouse_float = True

except Exception:
pass


if get_app().layout.container.floats:
try :
get_float_name = get_app().layout.container.floats[-1].name
except Exception:
get_float_name = ''

if get_float_name =='mouse':
if self.mouse_cord[0] <= x and self.mouse_cord[0] >= x-5:
if self.mouse_cord[1] == y-1:
res = []
res.append(HTML(style_tmp_red.format("Copy ")))
res.append("\n")
res.append(HTML(style_tmp.format("Cut")))
res.append("\n")
res.append(HTML(style_tmp.format("Paste")))
res.append("\n")
get_app().layout.container.floats[-1].content.content.text=merge_formatted_text(res)
self.mouse_select = 'Copy'
elif self.mouse_cord[1] == y-2:
res = []
res.append(HTML(style_tmp.format("Copy")))
res.append("\n")
res.append(HTML(style_tmp_red.format("Cut ")))
res.append("\n")
res.append(HTML(style_tmp.format("Paste")))
res.append("\n")
get_app().layout.container.floats[-1].content.content.text=merge_formatted_text(res)
self.mouse_select = 'Cut'
elif self.mouse_cord[1] == y-3:
res = []
res.append(HTML(style_tmp.format("Copy")))
res.append("\n")
res.append(HTML(style_tmp.format("Cut")))
res.append("\n")
res.append(HTML(style_tmp_red.format("Paste")))
res.append("\n")
get_app().layout.container.floats[-1].content.content.text=merge_formatted_text(res)
self.mouse_select = 'Paste'
else:
self.mouse_select = 'None'
else:
res = []
res.append(HTML(style_tmp.format("Copy")))
res.append("\n")
res.append(HTML(style_tmp.format("Cut")))
res.append("\n")
res.append(HTML(style_tmp.format("Paste")))
res.append("\n")
get_app().layout.container.floats[-1].content.content.text=merge_formatted_text(res)
self.mouse_select = 'None'

def up(self, ev: KeyPressEvent) -> None:
get_app().layout.focus(Frame(self.nav_bar.nav_window))
Expand Down Expand Up @@ -548,7 +718,8 @@ def custom_handler():
if on_selection_changed:
rl._handle_enter = custom_handler

v = VSplit([Label(text=title, width=len(title), style=style), rl])
v = VSplit([Window(FormattedTextControl(title), width=len(title)+1, style=style,), rl], padding=1)

v.me = rl

return v
Expand Down Expand Up @@ -633,7 +804,7 @@ async def coroutine():
result = await self.show_dialog_as_float(dialog)
try:
self.layout.focus(focused_before)
except:
except Exception:
self.layout.focus(self.center_frame)

return result
Expand Down
Loading