data-sourcerer 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data_sourcerer-0.1.0.dist-info/METADATA +52 -0
- data_sourcerer-0.1.0.dist-info/RECORD +95 -0
- data_sourcerer-0.1.0.dist-info/WHEEL +5 -0
- data_sourcerer-0.1.0.dist-info/entry_points.txt +2 -0
- data_sourcerer-0.1.0.dist-info/licenses/LICENSE +21 -0
- data_sourcerer-0.1.0.dist-info/top_level.txt +1 -0
- sourcerer/__init__.py +15 -0
- sourcerer/domain/__init__.py +13 -0
- sourcerer/domain/access_credentials/__init__.py +7 -0
- sourcerer/domain/access_credentials/entities.py +53 -0
- sourcerer/domain/access_credentials/exceptions.py +17 -0
- sourcerer/domain/access_credentials/repositories.py +84 -0
- sourcerer/domain/access_credentials/services.py +91 -0
- sourcerer/domain/file_system/__init__.py +7 -0
- sourcerer/domain/file_system/entities.py +70 -0
- sourcerer/domain/file_system/exceptions.py +17 -0
- sourcerer/domain/file_system/services.py +64 -0
- sourcerer/domain/shared/__init__.py +6 -0
- sourcerer/domain/shared/entities.py +18 -0
- sourcerer/domain/storage_provider/__init__.py +7 -0
- sourcerer/domain/storage_provider/entities.py +86 -0
- sourcerer/domain/storage_provider/exceptions.py +17 -0
- sourcerer/domain/storage_provider/services.py +130 -0
- sourcerer/infrastructure/__init__.py +13 -0
- sourcerer/infrastructure/access_credentials/__init__.py +7 -0
- sourcerer/infrastructure/access_credentials/exceptions.py +16 -0
- sourcerer/infrastructure/access_credentials/registry.py +120 -0
- sourcerer/infrastructure/access_credentials/repositories.py +119 -0
- sourcerer/infrastructure/access_credentials/services.py +396 -0
- sourcerer/infrastructure/db/__init__.py +6 -0
- sourcerer/infrastructure/db/config.py +73 -0
- sourcerer/infrastructure/db/models.py +47 -0
- sourcerer/infrastructure/file_system/__init__.py +7 -0
- sourcerer/infrastructure/file_system/exceptions.py +89 -0
- sourcerer/infrastructure/file_system/services.py +147 -0
- sourcerer/infrastructure/storage_provider/__init__.py +7 -0
- sourcerer/infrastructure/storage_provider/exceptions.py +78 -0
- sourcerer/infrastructure/storage_provider/registry.py +84 -0
- sourcerer/infrastructure/storage_provider/services.py +509 -0
- sourcerer/infrastructure/utils.py +106 -0
- sourcerer/presentation/__init__.py +12 -0
- sourcerer/presentation/app.py +36 -0
- sourcerer/presentation/di_container.py +46 -0
- sourcerer/presentation/screens/__init__.py +0 -0
- sourcerer/presentation/screens/critical_error/__init__.py +0 -0
- sourcerer/presentation/screens/critical_error/main.py +78 -0
- sourcerer/presentation/screens/critical_error/styles.tcss +41 -0
- sourcerer/presentation/screens/file_system_finder/main.py +248 -0
- sourcerer/presentation/screens/file_system_finder/styles.tcss +44 -0
- sourcerer/presentation/screens/file_system_finder/widgets/__init__.py +0 -0
- sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py +810 -0
- sourcerer/presentation/screens/main/__init__.py +0 -0
- sourcerer/presentation/screens/main/main.py +469 -0
- sourcerer/presentation/screens/main/messages/__init__.py +0 -0
- sourcerer/presentation/screens/main/messages/delete_request.py +12 -0
- sourcerer/presentation/screens/main/messages/download_request.py +12 -0
- sourcerer/presentation/screens/main/messages/preview_request.py +10 -0
- sourcerer/presentation/screens/main/messages/resizing_rule.py +21 -0
- sourcerer/presentation/screens/main/messages/select_storage_item.py +11 -0
- sourcerer/presentation/screens/main/messages/uncheck_files_request.py +8 -0
- sourcerer/presentation/screens/main/messages/upload_request.py +10 -0
- sourcerer/presentation/screens/main/mixins/__init__.py +0 -0
- sourcerer/presentation/screens/main/mixins/resize_containers_watcher_mixin.py +144 -0
- sourcerer/presentation/screens/main/styles.tcss +32 -0
- sourcerer/presentation/screens/main/widgets/__init__.py +0 -0
- sourcerer/presentation/screens/main/widgets/gradient.py +45 -0
- sourcerer/presentation/screens/main/widgets/resizing_rule.py +67 -0
- sourcerer/presentation/screens/main/widgets/storage_content.py +691 -0
- sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py +143 -0
- sourcerer/presentation/screens/preview_content/__init__.py +0 -0
- sourcerer/presentation/screens/preview_content/main.py +59 -0
- sourcerer/presentation/screens/preview_content/styles.tcss +26 -0
- sourcerer/presentation/screens/provider_creds_list/__init__.py +0 -0
- sourcerer/presentation/screens/provider_creds_list/main.py +164 -0
- sourcerer/presentation/screens/provider_creds_list/styles.tcss +65 -0
- sourcerer/presentation/screens/provider_creds_registration/__init__.py +0 -0
- sourcerer/presentation/screens/provider_creds_registration/main.py +264 -0
- sourcerer/presentation/screens/provider_creds_registration/styles.tcss +42 -0
- sourcerer/presentation/screens/question/__init__.py +0 -0
- sourcerer/presentation/screens/question/main.py +31 -0
- sourcerer/presentation/screens/question/styles.tcss +33 -0
- sourcerer/presentation/screens/shared/__init__.py +0 -0
- sourcerer/presentation/screens/shared/containers.py +13 -0
- sourcerer/presentation/screens/shared/widgets/__init__.py +0 -0
- sourcerer/presentation/screens/shared/widgets/button.py +54 -0
- sourcerer/presentation/screens/shared/widgets/labeled_input.py +80 -0
- sourcerer/presentation/screens/storage_action_progress/__init__.py +0 -0
- sourcerer/presentation/screens/storage_action_progress/main.py +476 -0
- sourcerer/presentation/screens/storage_action_progress/styles.tcss +43 -0
- sourcerer/presentation/settings.py +31 -0
- sourcerer/presentation/themes/__init__.py +0 -0
- sourcerer/presentation/themes/github_dark.py +21 -0
- sourcerer/presentation/utils.py +69 -0
- sourcerer/settings.py +72 -0
- sourcerer/utils.py +32 -0
@@ -0,0 +1,143 @@
|
|
1
|
+
"""Storage list sidebar widget for the Sourcerer application.
|
2
|
+
|
3
|
+
This module provides widgets for displaying and interacting with the list of
|
4
|
+
storage providers in the sidebar. It handles storage grouping by provider type
|
5
|
+
and selection of storage items.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from collections import namedtuple
|
9
|
+
from itertools import groupby
|
10
|
+
from typing import Dict, List
|
11
|
+
|
12
|
+
from textual import events
|
13
|
+
from textual.app import ComposeResult
|
14
|
+
from textual.containers import VerticalScroll, Horizontal, Container
|
15
|
+
from textual.reactive import reactive
|
16
|
+
from textual.widgets import Label, Rule
|
17
|
+
|
18
|
+
from sourcerer.domain.shared.entities import StorageProvider
|
19
|
+
from sourcerer.domain.storage_provider.entities import Storage
|
20
|
+
from sourcerer.presentation.screens.main.messages.select_storage_item import (
|
21
|
+
SelectStorageItem,
|
22
|
+
)
|
23
|
+
from sourcerer.presentation.screens.main.widgets.gradient import GradientWidget
|
24
|
+
|
25
|
+
STORAGE_ICONS = {
|
26
|
+
StorageProvider.S3: "🟠",
|
27
|
+
StorageProvider.GoogleCloudStorage: "🔵",
|
28
|
+
"azure": "⚪️",
|
29
|
+
}
|
30
|
+
"""Mapping of storage provider types to their display icons."""
|
31
|
+
|
32
|
+
|
33
|
+
class StorageItem(Label):
|
34
|
+
"""Widget for displaying and interacting with a single storage item.
|
35
|
+
|
36
|
+
This widget represents a storage instance in the sidebar list, allowing
|
37
|
+
selection and visual feedback on hover.
|
38
|
+
"""
|
39
|
+
|
40
|
+
DEFAULT_CSS = """
|
41
|
+
StorageItem {
|
42
|
+
width: 90%;
|
43
|
+
padding-left: 1;
|
44
|
+
height: auto;
|
45
|
+
margin:0;
|
46
|
+
text-overflow: ellipsis;
|
47
|
+
text-wrap: nowrap;
|
48
|
+
|
49
|
+
& > :hover {
|
50
|
+
background: $warning;
|
51
|
+
color: $panel;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
"""
|
55
|
+
|
56
|
+
def __init__(self, storage_name, access_credentials_uuid, *args, **kwargs):
|
57
|
+
"""Initialize a storage item widget.
|
58
|
+
|
59
|
+
Args:
|
60
|
+
storage_name: The name of the storage instance
|
61
|
+
access_credentials_uuid: UUID of the access credentials being used
|
62
|
+
"""
|
63
|
+
self.storage_name = storage_name
|
64
|
+
self.access_credentials_uuid = access_credentials_uuid
|
65
|
+
|
66
|
+
super().__init__(*args, **kwargs)
|
67
|
+
|
68
|
+
def on_click(self, _: events.Click) -> None:
|
69
|
+
"""Handle click events to select the storage item."""
|
70
|
+
self.post_message(
|
71
|
+
SelectStorageItem(
|
72
|
+
self.storage_name, access_credentials_uuid=self.access_credentials_uuid
|
73
|
+
)
|
74
|
+
)
|
75
|
+
|
76
|
+
|
77
|
+
class StorageListSidebar(VerticalScroll):
|
78
|
+
"""Sidebar widget for displaying the list of storage providers.
|
79
|
+
|
80
|
+
This widget manages the display of storage providers grouped by their type,
|
81
|
+
showing provider icons and storage names in a scrollable list.
|
82
|
+
|
83
|
+
Attributes:
|
84
|
+
storages: Dictionary mapping provider types to lists of storage instances
|
85
|
+
"""
|
86
|
+
|
87
|
+
storages: reactive[Dict[str, List[Storage]]] = reactive({}, recompose=True)
|
88
|
+
|
89
|
+
DEFAULT_CSS = """
|
90
|
+
StorageListSidebar {
|
91
|
+
padding-right: 0;
|
92
|
+
margin-right: 0;
|
93
|
+
& > .storage-group {
|
94
|
+
height: auto;
|
95
|
+
margin-bottom: 1;
|
96
|
+
#rule-left {
|
97
|
+
width: 1;
|
98
|
+
}
|
99
|
+
|
100
|
+
Horizontal {
|
101
|
+
height: auto;
|
102
|
+
}
|
103
|
+
Rule.-horizontal {
|
104
|
+
height: 1;
|
105
|
+
margin: 0 0;
|
106
|
+
|
107
|
+
}
|
108
|
+
.storage-letter {
|
109
|
+
color: $secondary;
|
110
|
+
padding: 0 1;
|
111
|
+
}
|
112
|
+
|
113
|
+
}
|
114
|
+
}
|
115
|
+
"""
|
116
|
+
|
117
|
+
def compose(self) -> ComposeResult:
|
118
|
+
with Container(id="header"):
|
119
|
+
yield GradientWidget("🧙SOURCERER", id="left-middle")
|
120
|
+
StorageData = namedtuple("Storage", ["access_credentials_uuid", "storage"])
|
121
|
+
storages = [
|
122
|
+
StorageData(access_credentials_uuid, storage)
|
123
|
+
for access_credentials_uuid, storages in self.storages.items()
|
124
|
+
for storage in storages
|
125
|
+
]
|
126
|
+
storages = sorted(storages, key=lambda x: x.storage.storage)
|
127
|
+
|
128
|
+
for letter, storages in groupby(storages, key=lambda x: x.storage.storage[0]):
|
129
|
+
with Container(id=f"group-{letter}", classes="storage-group"):
|
130
|
+
yield Horizontal(
|
131
|
+
Rule(id="rule-left"),
|
132
|
+
Label(letter.upper(), classes="storage-letter"),
|
133
|
+
Rule(),
|
134
|
+
)
|
135
|
+
|
136
|
+
for item in storages:
|
137
|
+
yield StorageItem(
|
138
|
+
renderable=STORAGE_ICONS.get(item.storage.provider, "")
|
139
|
+
+ " "
|
140
|
+
+ item.storage.storage,
|
141
|
+
storage_name=item.storage.storage,
|
142
|
+
access_credentials_uuid=item.access_credentials_uuid,
|
143
|
+
)
|
File without changes
|
@@ -0,0 +1,59 @@
|
|
1
|
+
from rich.syntax import Syntax
|
2
|
+
from textual import on
|
3
|
+
from textual.app import ComposeResult
|
4
|
+
from textual.containers import Container, Horizontal
|
5
|
+
from textual.screen import ModalScreen
|
6
|
+
from textual.widgets import RichLog, LoadingIndicator
|
7
|
+
|
8
|
+
from sourcerer.infrastructure.access_credentials.services import CredentialsService
|
9
|
+
from sourcerer.infrastructure.storage_provider.exceptions import (
|
10
|
+
ReadStorageItemsException,
|
11
|
+
)
|
12
|
+
from sourcerer.presentation.screens.shared.widgets.button import Button
|
13
|
+
from sourcerer.presentation.utils import get_provider_service_by_access_uuid
|
14
|
+
|
15
|
+
|
16
|
+
class PreviewContentScreen(ModalScreen):
|
17
|
+
CSS_PATH = "styles.tcss"
|
18
|
+
|
19
|
+
def __init__(self, storage_name, key, access_credentials_uuid, *args, **kwargs):
|
20
|
+
super().__init__(*args, **kwargs)
|
21
|
+
|
22
|
+
self.storage_name = storage_name
|
23
|
+
self.key = key
|
24
|
+
self.access_credentials_uuid = access_credentials_uuid
|
25
|
+
|
26
|
+
def compose(self) -> ComposeResult:
|
27
|
+
with Container(id="PreviewContentScreen"):
|
28
|
+
yield LoadingIndicator(id="loading")
|
29
|
+
yield RichLog(highlight=True, markup=True, auto_scroll=False)
|
30
|
+
with Horizontal(id="controls"):
|
31
|
+
yield Button("Close", name="cancel")
|
32
|
+
|
33
|
+
def on_mount(self) -> None:
|
34
|
+
"""Called when the DOM is ready."""
|
35
|
+
|
36
|
+
credentials_service = CredentialsService()
|
37
|
+
provider_service = get_provider_service_by_access_uuid(
|
38
|
+
self.access_credentials_uuid, credentials_service
|
39
|
+
)
|
40
|
+
if not provider_service:
|
41
|
+
self.notify("Could not read file :(", severity="error")
|
42
|
+
return
|
43
|
+
try:
|
44
|
+
content = provider_service.read_storage_item(self.storage_name, self.key)
|
45
|
+
except ReadStorageItemsException:
|
46
|
+
self.notify("Could not read file :(", severity="error")
|
47
|
+
return
|
48
|
+
self.query_one("#loading").remove()
|
49
|
+
|
50
|
+
text_log = self.query_one(RichLog)
|
51
|
+
lexer = Syntax.guess_lexer(self.key, content)
|
52
|
+
content = Syntax(content, lexer, line_numbers=True, theme="ansi_dark")
|
53
|
+
text_log.write(content)
|
54
|
+
|
55
|
+
@on(Button.Click)
|
56
|
+
def on_button_click(self, event: Button.Click) -> None:
|
57
|
+
"""Handle button click events."""
|
58
|
+
if event.action == "cancel":
|
59
|
+
self.dismiss()
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
Container {
|
3
|
+
height: auto;
|
4
|
+
}
|
5
|
+
|
6
|
+
|
7
|
+
PreviewContentScreen {
|
8
|
+
align: center middle;
|
9
|
+
content-align: center top;
|
10
|
+
|
11
|
+
|
12
|
+
& > #PreviewContentScreen {
|
13
|
+
padding: 1 2 0 2;
|
14
|
+
margin: 0 0;
|
15
|
+
width: 90;
|
16
|
+
height: 40;
|
17
|
+
border: solid $secondary-background;
|
18
|
+
border-title-color: $primary-lighten-2;
|
19
|
+
|
20
|
+
RichLog {
|
21
|
+
background: transparent;
|
22
|
+
}
|
23
|
+
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
File without changes
|
@@ -0,0 +1,164 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from enum import Enum
|
3
|
+
|
4
|
+
from textual import on
|
5
|
+
from textual.app import ComposeResult
|
6
|
+
from textual.containers import Container, Horizontal, VerticalScroll
|
7
|
+
from textual.message import Message
|
8
|
+
from textual.reactive import reactive
|
9
|
+
from textual.screen import ModalScreen
|
10
|
+
from textual.widgets import Label, Checkbox
|
11
|
+
|
12
|
+
from sourcerer.domain.access_credentials.entities import Credentials
|
13
|
+
from sourcerer.infrastructure.access_credentials.services import CredentialsService
|
14
|
+
from sourcerer.presentation.screens.provider_creds_registration.main import (
|
15
|
+
ProviderCredsRegistrationScreen,
|
16
|
+
ProviderCredentialsEntry,
|
17
|
+
)
|
18
|
+
from sourcerer.presentation.screens.shared.widgets.button import Button
|
19
|
+
|
20
|
+
|
21
|
+
class ControlsEnum(Enum):
|
22
|
+
CANCEL = "Cancel"
|
23
|
+
|
24
|
+
|
25
|
+
class ProviderCredentialsRow(Horizontal):
|
26
|
+
@dataclass
|
27
|
+
class ChangeActiveStatus(Message):
|
28
|
+
uuid: str
|
29
|
+
active: bool
|
30
|
+
|
31
|
+
def __init__(self, row: Credentials, *args, **kwargs):
|
32
|
+
super().__init__(*args, **kwargs)
|
33
|
+
self.row = row
|
34
|
+
|
35
|
+
def compose(self) -> ComposeResult:
|
36
|
+
yield Checkbox(
|
37
|
+
value=self.row.active, classes="credentials_active", name=self.row.uuid
|
38
|
+
)
|
39
|
+
yield Label(self.row.name, classes="credentials_name")
|
40
|
+
yield Label(self.row.provider, classes="credentials_provider")
|
41
|
+
yield Label(self.row.credentials_type, classes="credentials_auth_method")
|
42
|
+
|
43
|
+
def on_mouse_move(self, _) -> None:
|
44
|
+
"""Change background color when hovered."""
|
45
|
+
self.add_class("active")
|
46
|
+
|
47
|
+
def on_leave(self, _) -> None:
|
48
|
+
"""Reset background color when mouse leaves."""
|
49
|
+
self.remove_class("active")
|
50
|
+
|
51
|
+
@on(Checkbox.Changed)
|
52
|
+
def on_checkbox_change(self, event: Checkbox.Changed):
|
53
|
+
"""
|
54
|
+
Handle checkbox state changes by updating the row's active status and posting a ChangeActiveStatus message.
|
55
|
+
|
56
|
+
Args:
|
57
|
+
event (Checkbox.Changed): The checkbox change event containing the new value.
|
58
|
+
"""
|
59
|
+
self.row.active = event.value
|
60
|
+
self.post_message(self.ChangeActiveStatus(self.row.uuid, self.row.active))
|
61
|
+
|
62
|
+
|
63
|
+
class ProviderCredsListScreen(ModalScreen):
|
64
|
+
CSS_PATH = "styles.tcss"
|
65
|
+
|
66
|
+
MAIN_CONTAINER_ID = "ProviderCredsListScreen"
|
67
|
+
SETTINGS_CONTAINER_ID = "settings"
|
68
|
+
PROVIDER_SELECTOR_ID = "provider_selector"
|
69
|
+
CREDENTIALS_TYPE_SELECTOR_ID = "credentials_type_select"
|
70
|
+
CREDENTIALS_FIELDS_CONTAINER_ID = "credentials_fields_container"
|
71
|
+
|
72
|
+
PROVIDERS_NAME = "providers"
|
73
|
+
AUTH_METHODS_NAME = "auth_methods"
|
74
|
+
|
75
|
+
credentials_list = reactive([], recompose=True)
|
76
|
+
|
77
|
+
def __init__(self, *args, **kwargs):
|
78
|
+
super().__init__(*args, **kwargs)
|
79
|
+
self.credentials_service = CredentialsService()
|
80
|
+
|
81
|
+
def compose(self) -> ComposeResult:
|
82
|
+
with Container(id=self.MAIN_CONTAINER_ID):
|
83
|
+
yield Container(
|
84
|
+
Button(
|
85
|
+
"+Add new registration",
|
86
|
+
name="add_registration",
|
87
|
+
classes="add_registration_button",
|
88
|
+
),
|
89
|
+
id="right-top",
|
90
|
+
)
|
91
|
+
with VerticalScroll(id=self.SETTINGS_CONTAINER_ID):
|
92
|
+
with Horizontal():
|
93
|
+
yield Label("Active", classes="credentials_active")
|
94
|
+
yield Label("Name", classes="credentials_name")
|
95
|
+
yield Label("Provider", classes="credentials_provider")
|
96
|
+
yield Label("Auth method", classes="credentials_auth_method")
|
97
|
+
for row in self.credentials_list:
|
98
|
+
yield ProviderCredentialsRow(row, classes="credentials_row")
|
99
|
+
with Horizontal(id="controls"):
|
100
|
+
yield Button(ControlsEnum.CANCEL.value, name=ControlsEnum.CANCEL.name)
|
101
|
+
|
102
|
+
def on_compose(self):
|
103
|
+
"""
|
104
|
+
Initialize the screen by refreshing the credentials list when the screen is composed.
|
105
|
+
"""
|
106
|
+
self.refresh_credentials_list()
|
107
|
+
|
108
|
+
def refresh_credentials_list(self):
|
109
|
+
"""
|
110
|
+
Refresh the credentials list by retrieving the latest credentials from the credentials service.
|
111
|
+
"""
|
112
|
+
self.credentials_list = self.credentials_service.list()
|
113
|
+
|
114
|
+
def create_provider_creds_registration(
|
115
|
+
self, credentials_entry: ProviderCredentialsEntry
|
116
|
+
):
|
117
|
+
"""
|
118
|
+
Create a new provider credentials registration.
|
119
|
+
|
120
|
+
Stores the provided credentials entry using its associated service and refreshes the credentials list.
|
121
|
+
|
122
|
+
Args:
|
123
|
+
credentials_entry (ProviderCredentialsEntry): The credentials entry to register.
|
124
|
+
"""
|
125
|
+
if not credentials_entry:
|
126
|
+
return
|
127
|
+
service = credentials_entry.cloud_storage_provider_credentials_service() # type: ignore
|
128
|
+
service.store(credentials_entry.name, credentials_entry.fields)
|
129
|
+
self.refresh_credentials_list()
|
130
|
+
|
131
|
+
@on(Button.Click)
|
132
|
+
def on_control_button_click(self, event: Button.Click):
|
133
|
+
"""
|
134
|
+
Handle click events for control buttons.
|
135
|
+
|
136
|
+
Dismisses the screen if the cancel button is clicked, or opens the provider credentials registration screen if
|
137
|
+
the add registration button is clicked.
|
138
|
+
|
139
|
+
Args:
|
140
|
+
event (Button.Click): The button click event.
|
141
|
+
"""
|
142
|
+
if event.action == ControlsEnum.CANCEL.name:
|
143
|
+
self.dismiss()
|
144
|
+
if event.action == "add_registration":
|
145
|
+
self.app.push_screen(
|
146
|
+
ProviderCredsRegistrationScreen(),
|
147
|
+
callback=self.create_provider_creds_registration, # type: ignore
|
148
|
+
)
|
149
|
+
|
150
|
+
@on(ProviderCredentialsRow.ChangeActiveStatus)
|
151
|
+
def on_change_active_status(self, event: ProviderCredentialsRow.ChangeActiveStatus):
|
152
|
+
"""
|
153
|
+
Handle changes to the active status of a provider credentials row.
|
154
|
+
|
155
|
+
Activates or deactivates the credentials based on the event, then refreshes the credentials list.
|
156
|
+
|
157
|
+
Args:
|
158
|
+
event (ProviderCredentialsRow.ChangeActiveStatus): Event containing the credentials UUID and new status.
|
159
|
+
"""
|
160
|
+
if event.active:
|
161
|
+
self.credentials_service.activate(event.uuid)
|
162
|
+
else:
|
163
|
+
self.credentials_service.deactivate(event.uuid)
|
164
|
+
self.refresh_credentials_list()
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
Container {
|
3
|
+
height: auto;
|
4
|
+
}
|
5
|
+
|
6
|
+
Label {
|
7
|
+
padding-left: 1;
|
8
|
+
}
|
9
|
+
|
10
|
+
ProviderCredsListScreen {
|
11
|
+
align: center middle;
|
12
|
+
content-align: center top;
|
13
|
+
|
14
|
+
& > #ProviderCredsListScreen {
|
15
|
+
padding: 1 2 0 2;
|
16
|
+
margin: 0 0;
|
17
|
+
width: 60%;
|
18
|
+
height: 60%;
|
19
|
+
border: solid $secondary-background;
|
20
|
+
|
21
|
+
#right-top {
|
22
|
+
align: right top;
|
23
|
+
|
24
|
+
.add_registration_button {
|
25
|
+
color: $success-darken-2;
|
26
|
+
}
|
27
|
+
|
28
|
+
margin-bottom: 1;
|
29
|
+
}
|
30
|
+
|
31
|
+
ProviderCredentialsRow.active {
|
32
|
+
background: $primary-lighten-2;
|
33
|
+
}
|
34
|
+
|
35
|
+
ProviderCredentialsRow, Horizontal {
|
36
|
+
height: auto;
|
37
|
+
}
|
38
|
+
|
39
|
+
.credentials_active {
|
40
|
+
width: 10%;
|
41
|
+
background: transparent;
|
42
|
+
border: none;
|
43
|
+
}
|
44
|
+
|
45
|
+
.credentials_name {
|
46
|
+
width: 30%;
|
47
|
+
}
|
48
|
+
|
49
|
+
.credentials_provider {
|
50
|
+
width: 30%;
|
51
|
+
}
|
52
|
+
|
53
|
+
.credentials_auth_method {
|
54
|
+
width: 30%;
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
& > Select {
|
59
|
+
margin-bottom: 1;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
|
65
|
+
|
File without changes
|