ositah 25.6.dev1__py3-none-any.whl → 25.9.dev2__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.
Potentially problematic release.
This version of ositah might be problematic. Click here for more details.
- ositah/app.py +17 -17
- ositah/apps/analysis.py +785 -785
- ositah/apps/configuration/callbacks.py +916 -916
- ositah/apps/configuration/main.py +546 -546
- ositah/apps/configuration/parameters.py +74 -74
- ositah/apps/configuration/tools.py +112 -112
- ositah/apps/export.py +1209 -1191
- ositah/apps/validation/callbacks.py +240 -240
- ositah/apps/validation/main.py +89 -89
- ositah/apps/validation/parameters.py +25 -25
- ositah/apps/validation/tables.py +646 -646
- ositah/apps/validation/tools.py +552 -552
- ositah/assets/arrow_down_up.svg +3 -3
- ositah/assets/ositah.css +53 -53
- ositah/assets/sort_ascending.svg +4 -4
- ositah/assets/sort_descending.svg +5 -5
- ositah/assets/sorttable.js +499 -499
- ositah/main.py +449 -449
- ositah/ositah.example.cfg +229 -229
- ositah/static/style.css +53 -53
- ositah/templates/base.html +22 -22
- ositah/templates/bootstrap_login.html +38 -38
- ositah/templates/login_form.html +26 -26
- ositah/utils/agents.py +124 -124
- ositah/utils/authentication.py +287 -287
- ositah/utils/cache.py +19 -19
- ositah/utils/core.py +13 -13
- ositah/utils/exceptions.py +64 -64
- ositah/utils/hito_db.py +51 -51
- ositah/utils/hito_db_model.py +253 -253
- ositah/utils/menus.py +339 -339
- ositah/utils/period.py +139 -139
- ositah/utils/projects.py +1179 -1178
- ositah/utils/teams.py +42 -42
- ositah/utils/utils.py +474 -474
- {ositah-25.6.dev1.dist-info → ositah-25.9.dev2.dist-info}/METADATA +149 -150
- ositah-25.9.dev2.dist-info/RECORD +46 -0
- {ositah-25.6.dev1.dist-info → ositah-25.9.dev2.dist-info}/licenses/LICENSE +29 -29
- ositah-25.6.dev1.dist-info/RECORD +0 -46
- {ositah-25.6.dev1.dist-info → ositah-25.9.dev2.dist-info}/WHEEL +0 -0
- {ositah-25.6.dev1.dist-info → ositah-25.9.dev2.dist-info}/entry_points.txt +0 -0
- {ositah-25.6.dev1.dist-info → ositah-25.9.dev2.dist-info}/top_level.txt +0 -0
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Parameters related to Dash components in the Configuration sub-application
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
CONFIGURATION_TAB_MENU_ID = "configuration-tabs"
|
|
6
|
-
TAB_ID_NSIP_PROJECT_SYNC = "nsip-project-sync-tab"
|
|
7
|
-
TAB_ID_ACTIVITY_TEAMS = "config-activity-teams-tab"
|
|
8
|
-
TAB_ID_DECLARATION_PERIODS = "config-validation-period-tab"
|
|
9
|
-
TAB_ID_PROJECT_MGT = "config-project-mgt-tab"
|
|
10
|
-
|
|
11
|
-
ACTIVITY_TEAMS_MASTERPROJECTS_ID = "config-activity-teams-masterprojects"
|
|
12
|
-
ACTIVITY_TEAMS_PROJECTS_ID = "config-activity-teams-projects"
|
|
13
|
-
ACTIVITY_TEAMS_LAB_TEAMS_ID = "config-activity-teams-lab-teams"
|
|
14
|
-
ACTIVITY_TEAMS_SELECTED_TEAMS_ID = "config-activity-teams-selected-teams"
|
|
15
|
-
ACTIVITY_TEAMS_BUTTON_ADD_ID = "config-activity-teams-add-team"
|
|
16
|
-
ACTIVITY_TEAMS_BUTTON_CANCEL_ID = "config-activity-teams-cancel-team"
|
|
17
|
-
ACTIVITY_TEAMS_BUTTON_REMOVE_ID = "config-activity-teams-remove-team"
|
|
18
|
-
ACTIVITY_TEAMS_BUTTON_UPDATE_ID = "config-activity-teams-update-button"
|
|
19
|
-
ACTIVITY_TEAMS_PROJECT_ACTIVITY_ID = "config-activity-teams-is-project"
|
|
20
|
-
ACTIVITY_TEAMS_ADDED_TEAMS_ID = "config-activity-teams-added-teams"
|
|
21
|
-
ACTIVITY_TEAMS_REMOVED_TEAMS_ID = "config-activity-teams-removed-teams"
|
|
22
|
-
ACTIVITY_TEAMS_STATUS_ID = "config-activity-teams-status-msg"
|
|
23
|
-
ACTIVITY_TEAMS_RESET_INDICATOR_ID = "config-activity-teams-reset-indicator"
|
|
24
|
-
ACTIVITY_TEAMS_LIST_MAX_SIZE = 10
|
|
25
|
-
ACTIVITY_TEAMS_LIST_BOX_WIDTH = 5
|
|
26
|
-
# Attempt to reduce list box width on very large display (2500+px) but unfortunately
|
|
27
|
-
# Bootstrap xxl is 1400+px thus including full HD. Not clear how to tune mediaclass definitions.
|
|
28
|
-
ACTIVITY_TEAMS_LIST_BOX_WIDTH_XXL = 5
|
|
29
|
-
ACTIVITY_TEAMS_LIST_BOX_INTERVAL = 1
|
|
30
|
-
|
|
31
|
-
DECLARATION_PERIOD_END_DATE_ID = "config-declaration-period-end"
|
|
32
|
-
DECLARATION_PERIOD_NAME_ID = "config-declaration-period-name"
|
|
33
|
-
DECLARATION_PERIOD_PARAMS_ID = "config-declaration-period-params"
|
|
34
|
-
DECLARATION_PERIOD_START_DATE_ID = "config-declaration-period-start"
|
|
35
|
-
DECLARATION_PERIOD_VALIDATION_DATE_ID = "config-declaration-period-validation"
|
|
36
|
-
DECLARATION_PERIODS_ID = "config-declaration-periods"
|
|
37
|
-
DECLARATION_PERIODS_CREATE_NEW_ID = "config-declaration-periods-create-new"
|
|
38
|
-
DECLARATION_PERIODS_CREATE_DIV_ID = "config-declaration-periods-create-div"
|
|
39
|
-
DECLARATION_PERIODS_CREATE_CLICK_ID = "config-declaration-periods-create-click-saved"
|
|
40
|
-
DECLARATION_PERIODS_SAVE_NEW_ID = "config-declaration-periods-save-new"
|
|
41
|
-
DECLARATION_PERIODS_SAVE_DIV_ID = "config-declaration-periods-save-div"
|
|
42
|
-
DECLARATION_PERIODS_STATUS_ID = "config-declaration-periods-status"
|
|
43
|
-
DECLARATION_PERIODS_STATUS_HIDDEN_ID = "config-declaration-periods-status-hidden"
|
|
44
|
-
DECLARATION_PERIODS_STATUS_VISIBLE_ID = "config-declaration-periods-status-visible"
|
|
45
|
-
DECLARATION_PERIODS_VALIDATION_ID = "config-declaration-periods-validation"
|
|
46
|
-
DECLARATION_PERIODS_LIST_MAX_SIZE = 10
|
|
47
|
-
|
|
48
|
-
NSIP_SYNC_SHOW_DIFF_ID = "nsip-sync-show-diff-button"
|
|
49
|
-
NSIP_SYNC_APPLY_DIFF_ID = "nsip-sync-apply-diff-button"
|
|
50
|
-
NSIP_SYNC_CONTENT_ID = "nsip-project-sync-content"
|
|
51
|
-
NSIP_SYNC_ACTIVITY_TYPE_ID = "nsip-sync-activity-type"
|
|
52
|
-
NSIP_SYNC_ACTIVITY_TYPE_PROJECT = 1
|
|
53
|
-
NSIP_SYNC_ACTIVITY_TYPE_OTHER = 2
|
|
54
|
-
|
|
55
|
-
PROJECT_MGT_MASTERPROJECT_LIST_ID = "project-mgt-masterproject-list"
|
|
56
|
-
PROJECT_MGT_PROJECT_LIST_ID = "project-mgt-project-list"
|
|
57
|
-
PROJECT_MGT_PROJECT_ACTIVITY_ID = "project-mgt-is-project"
|
|
58
|
-
PROJECT_MGT_PROJECT_TYPE_ID = "project-mgt-project-type"
|
|
59
|
-
PROJECT_MGT_ACTION_BUTTON_ID = "project-mgt-action-button"
|
|
60
|
-
PROJECT_MGT_ACTION_BUTTON_DISABLE = "Désactiver"
|
|
61
|
-
PROJECT_MGT_ACTION_BUTTON_ENABLE = "Réactiver"
|
|
62
|
-
PROJECT_MGT_STATUS_ID = "project-mgt-status"
|
|
63
|
-
PROJECT_MGT_PROJECT_TYPE_NSIP = 0
|
|
64
|
-
PROJECT_MGT_PROJECT_TYPE_LOCAL = 1
|
|
65
|
-
PROJECT_MGT_PROJECT_TYPE_DISABLED = 2
|
|
66
|
-
PROJECT_MGT_LIST_MAX_SIZE = 10
|
|
67
|
-
PROJECT_MGT_LIST_BOX_WIDTH = 5
|
|
68
|
-
PROJECT_MGT_LIST_BOX_WIDTH_XXL = 5
|
|
69
|
-
|
|
70
|
-
TABLE_NSIP_PROJECT_SYNC_ID = "nsip-project-sync"
|
|
71
|
-
|
|
72
|
-
PROJECT_CHANGE_ADDED = "Ajouté"
|
|
73
|
-
PROJECT_CHANGE_CHANGED = "Modifié"
|
|
74
|
-
PROJECT_CHANGE_REMOVED = "Supprimé"
|
|
1
|
+
"""
|
|
2
|
+
Parameters related to Dash components in the Configuration sub-application
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
CONFIGURATION_TAB_MENU_ID = "configuration-tabs"
|
|
6
|
+
TAB_ID_NSIP_PROJECT_SYNC = "nsip-project-sync-tab"
|
|
7
|
+
TAB_ID_ACTIVITY_TEAMS = "config-activity-teams-tab"
|
|
8
|
+
TAB_ID_DECLARATION_PERIODS = "config-validation-period-tab"
|
|
9
|
+
TAB_ID_PROJECT_MGT = "config-project-mgt-tab"
|
|
10
|
+
|
|
11
|
+
ACTIVITY_TEAMS_MASTERPROJECTS_ID = "config-activity-teams-masterprojects"
|
|
12
|
+
ACTIVITY_TEAMS_PROJECTS_ID = "config-activity-teams-projects"
|
|
13
|
+
ACTIVITY_TEAMS_LAB_TEAMS_ID = "config-activity-teams-lab-teams"
|
|
14
|
+
ACTIVITY_TEAMS_SELECTED_TEAMS_ID = "config-activity-teams-selected-teams"
|
|
15
|
+
ACTIVITY_TEAMS_BUTTON_ADD_ID = "config-activity-teams-add-team"
|
|
16
|
+
ACTIVITY_TEAMS_BUTTON_CANCEL_ID = "config-activity-teams-cancel-team"
|
|
17
|
+
ACTIVITY_TEAMS_BUTTON_REMOVE_ID = "config-activity-teams-remove-team"
|
|
18
|
+
ACTIVITY_TEAMS_BUTTON_UPDATE_ID = "config-activity-teams-update-button"
|
|
19
|
+
ACTIVITY_TEAMS_PROJECT_ACTIVITY_ID = "config-activity-teams-is-project"
|
|
20
|
+
ACTIVITY_TEAMS_ADDED_TEAMS_ID = "config-activity-teams-added-teams"
|
|
21
|
+
ACTIVITY_TEAMS_REMOVED_TEAMS_ID = "config-activity-teams-removed-teams"
|
|
22
|
+
ACTIVITY_TEAMS_STATUS_ID = "config-activity-teams-status-msg"
|
|
23
|
+
ACTIVITY_TEAMS_RESET_INDICATOR_ID = "config-activity-teams-reset-indicator"
|
|
24
|
+
ACTIVITY_TEAMS_LIST_MAX_SIZE = 10
|
|
25
|
+
ACTIVITY_TEAMS_LIST_BOX_WIDTH = 5
|
|
26
|
+
# Attempt to reduce list box width on very large display (2500+px) but unfortunately
|
|
27
|
+
# Bootstrap xxl is 1400+px thus including full HD. Not clear how to tune mediaclass definitions.
|
|
28
|
+
ACTIVITY_TEAMS_LIST_BOX_WIDTH_XXL = 5
|
|
29
|
+
ACTIVITY_TEAMS_LIST_BOX_INTERVAL = 1
|
|
30
|
+
|
|
31
|
+
DECLARATION_PERIOD_END_DATE_ID = "config-declaration-period-end"
|
|
32
|
+
DECLARATION_PERIOD_NAME_ID = "config-declaration-period-name"
|
|
33
|
+
DECLARATION_PERIOD_PARAMS_ID = "config-declaration-period-params"
|
|
34
|
+
DECLARATION_PERIOD_START_DATE_ID = "config-declaration-period-start"
|
|
35
|
+
DECLARATION_PERIOD_VALIDATION_DATE_ID = "config-declaration-period-validation"
|
|
36
|
+
DECLARATION_PERIODS_ID = "config-declaration-periods"
|
|
37
|
+
DECLARATION_PERIODS_CREATE_NEW_ID = "config-declaration-periods-create-new"
|
|
38
|
+
DECLARATION_PERIODS_CREATE_DIV_ID = "config-declaration-periods-create-div"
|
|
39
|
+
DECLARATION_PERIODS_CREATE_CLICK_ID = "config-declaration-periods-create-click-saved"
|
|
40
|
+
DECLARATION_PERIODS_SAVE_NEW_ID = "config-declaration-periods-save-new"
|
|
41
|
+
DECLARATION_PERIODS_SAVE_DIV_ID = "config-declaration-periods-save-div"
|
|
42
|
+
DECLARATION_PERIODS_STATUS_ID = "config-declaration-periods-status"
|
|
43
|
+
DECLARATION_PERIODS_STATUS_HIDDEN_ID = "config-declaration-periods-status-hidden"
|
|
44
|
+
DECLARATION_PERIODS_STATUS_VISIBLE_ID = "config-declaration-periods-status-visible"
|
|
45
|
+
DECLARATION_PERIODS_VALIDATION_ID = "config-declaration-periods-validation"
|
|
46
|
+
DECLARATION_PERIODS_LIST_MAX_SIZE = 10
|
|
47
|
+
|
|
48
|
+
NSIP_SYNC_SHOW_DIFF_ID = "nsip-sync-show-diff-button"
|
|
49
|
+
NSIP_SYNC_APPLY_DIFF_ID = "nsip-sync-apply-diff-button"
|
|
50
|
+
NSIP_SYNC_CONTENT_ID = "nsip-project-sync-content"
|
|
51
|
+
NSIP_SYNC_ACTIVITY_TYPE_ID = "nsip-sync-activity-type"
|
|
52
|
+
NSIP_SYNC_ACTIVITY_TYPE_PROJECT = 1
|
|
53
|
+
NSIP_SYNC_ACTIVITY_TYPE_OTHER = 2
|
|
54
|
+
|
|
55
|
+
PROJECT_MGT_MASTERPROJECT_LIST_ID = "project-mgt-masterproject-list"
|
|
56
|
+
PROJECT_MGT_PROJECT_LIST_ID = "project-mgt-project-list"
|
|
57
|
+
PROJECT_MGT_PROJECT_ACTIVITY_ID = "project-mgt-is-project"
|
|
58
|
+
PROJECT_MGT_PROJECT_TYPE_ID = "project-mgt-project-type"
|
|
59
|
+
PROJECT_MGT_ACTION_BUTTON_ID = "project-mgt-action-button"
|
|
60
|
+
PROJECT_MGT_ACTION_BUTTON_DISABLE = "Désactiver"
|
|
61
|
+
PROJECT_MGT_ACTION_BUTTON_ENABLE = "Réactiver"
|
|
62
|
+
PROJECT_MGT_STATUS_ID = "project-mgt-status"
|
|
63
|
+
PROJECT_MGT_PROJECT_TYPE_NSIP = 0
|
|
64
|
+
PROJECT_MGT_PROJECT_TYPE_LOCAL = 1
|
|
65
|
+
PROJECT_MGT_PROJECT_TYPE_DISABLED = 2
|
|
66
|
+
PROJECT_MGT_LIST_MAX_SIZE = 10
|
|
67
|
+
PROJECT_MGT_LIST_BOX_WIDTH = 5
|
|
68
|
+
PROJECT_MGT_LIST_BOX_WIDTH_XXL = 5
|
|
69
|
+
|
|
70
|
+
TABLE_NSIP_PROJECT_SYNC_ID = "nsip-project-sync"
|
|
71
|
+
|
|
72
|
+
PROJECT_CHANGE_ADDED = "Ajouté"
|
|
73
|
+
PROJECT_CHANGE_CHANGED = "Modifié"
|
|
74
|
+
PROJECT_CHANGE_REMOVED = "Supprimé"
|
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Various functions used by Configure sub-application
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import re
|
|
6
|
-
|
|
7
|
-
import pandas as pd
|
|
8
|
-
|
|
9
|
-
from ositah.apps.configuration.parameters import (
|
|
10
|
-
PROJECT_MGT_PROJECT_TYPE_DISABLED,
|
|
11
|
-
PROJECT_MGT_PROJECT_TYPE_LOCAL,
|
|
12
|
-
)
|
|
13
|
-
from ositah.utils.projects import (
|
|
14
|
-
MASTERPROJECT_DELETED_ACTIVITY,
|
|
15
|
-
MASTERPROJECT_LOCAL_PROJECT,
|
|
16
|
-
get_all_hito_activities,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def list_box_empty(list_options):
|
|
21
|
-
"""
|
|
22
|
-
Check if the options of the list box contains only one entry corresponding to a
|
|
23
|
-
placeholder item.
|
|
24
|
-
|
|
25
|
-
:param team_list_items: options of a list box
|
|
26
|
-
:return: boolean (true if only a placeholder entry is present)
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
len(list_options) == 1
|
|
31
|
-
and list_options[0]["label"] is None
|
|
32
|
-
and list_options[0]["value"] is None
|
|
33
|
-
):
|
|
34
|
-
return True
|
|
35
|
-
else:
|
|
36
|
-
return False
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def get_masterprojects_items(project_activity, category: int = None) -> list:
|
|
40
|
-
"""
|
|
41
|
-
Build the item list for masterprojects to be displayed in a select compoenent
|
|
42
|
-
|
|
43
|
-
:param project_activity: True if it is a project rather than a Hito activity
|
|
44
|
-
:param category: one of PROJECT_MGT_PROJECT_TYPE_xxx values or None. If None, menas
|
|
45
|
-
all active (non disabled) projects/activities
|
|
46
|
-
:return: list of projects/activities
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
if category == PROJECT_MGT_PROJECT_TYPE_LOCAL:
|
|
50
|
-
# Local projects have no masterproject
|
|
51
|
-
return []
|
|
52
|
-
|
|
53
|
-
activities = get_all_hito_activities(project_activity)
|
|
54
|
-
masterproject_items = []
|
|
55
|
-
if category == PROJECT_MGT_PROJECT_TYPE_DISABLED:
|
|
56
|
-
disabled = pd.DataFrame()
|
|
57
|
-
disabled[["masterproject_real", "project_real"]] = activities[
|
|
58
|
-
activities.masterproject == MASTERPROJECT_DELETED_ACTIVITY
|
|
59
|
-
]["project"].str.split(" / ", n=1, expand=True)
|
|
60
|
-
for masterproject in sorted(
|
|
61
|
-
disabled["masterproject_real"].unique(),
|
|
62
|
-
key=lambda x: x.upper(),
|
|
63
|
-
):
|
|
64
|
-
masterproject_items.append({"label": masterproject, "value": masterproject})
|
|
65
|
-
else:
|
|
66
|
-
masterproject_items = sorted(
|
|
67
|
-
activities[
|
|
68
|
-
(activities.masterproject != MASTERPROJECT_DELETED_ACTIVITY)
|
|
69
|
-
& (activities.masterproject != MASTERPROJECT_LOCAL_PROJECT)
|
|
70
|
-
]["masterproject"].unique(),
|
|
71
|
-
key=lambda x: x.upper(),
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
return masterproject_items
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def get_projects_items(masterproject, project_activity, category: int = None) -> list:
|
|
78
|
-
"""
|
|
79
|
-
Build the item list for projects to be displayed in a select compoenent
|
|
80
|
-
|
|
81
|
-
:param masterproject: selected master project
|
|
82
|
-
:param project_activity: True if it is a project rather than a Hito activity
|
|
83
|
-
:param category: one of PROJECT_MGT_PROJECT_TYPE_xxx values or None. If None, menas
|
|
84
|
-
all active (non disabled) projects/activities
|
|
85
|
-
:return: list of projects/activities
|
|
86
|
-
"""
|
|
87
|
-
|
|
88
|
-
if category == PROJECT_MGT_PROJECT_TYPE_LOCAL:
|
|
89
|
-
project_prefix = masterproject
|
|
90
|
-
masterproject = MASTERPROJECT_LOCAL_PROJECT
|
|
91
|
-
elif category == PROJECT_MGT_PROJECT_TYPE_DISABLED:
|
|
92
|
-
project_prefix = masterproject
|
|
93
|
-
masterproject = MASTERPROJECT_DELETED_ACTIVITY
|
|
94
|
-
else:
|
|
95
|
-
project_prefix = None
|
|
96
|
-
|
|
97
|
-
if masterproject:
|
|
98
|
-
activities = get_all_hito_activities(project_activity)
|
|
99
|
-
project_items = []
|
|
100
|
-
for project in sorted(
|
|
101
|
-
activities[activities.masterproject == masterproject]["project"].unique(),
|
|
102
|
-
key=lambda x: x.upper(),
|
|
103
|
-
):
|
|
104
|
-
if project_prefix is None or re.match(rf"{project_prefix}", project):
|
|
105
|
-
if category == PROJECT_MGT_PROJECT_TYPE_DISABLED:
|
|
106
|
-
project_name = project.split("/")[1]
|
|
107
|
-
else:
|
|
108
|
-
project_name = project
|
|
109
|
-
project_items.append({"label": project_name, "value": project})
|
|
110
|
-
return project_items
|
|
111
|
-
else:
|
|
112
|
-
return []
|
|
1
|
+
"""
|
|
2
|
+
Various functions used by Configure sub-application
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
from ositah.apps.configuration.parameters import (
|
|
10
|
+
PROJECT_MGT_PROJECT_TYPE_DISABLED,
|
|
11
|
+
PROJECT_MGT_PROJECT_TYPE_LOCAL,
|
|
12
|
+
)
|
|
13
|
+
from ositah.utils.projects import (
|
|
14
|
+
MASTERPROJECT_DELETED_ACTIVITY,
|
|
15
|
+
MASTERPROJECT_LOCAL_PROJECT,
|
|
16
|
+
get_all_hito_activities,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def list_box_empty(list_options):
|
|
21
|
+
"""
|
|
22
|
+
Check if the options of the list box contains only one entry corresponding to a
|
|
23
|
+
placeholder item.
|
|
24
|
+
|
|
25
|
+
:param team_list_items: options of a list box
|
|
26
|
+
:return: boolean (true if only a placeholder entry is present)
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
if (
|
|
30
|
+
len(list_options) == 1
|
|
31
|
+
and list_options[0]["label"] is None
|
|
32
|
+
and list_options[0]["value"] is None
|
|
33
|
+
):
|
|
34
|
+
return True
|
|
35
|
+
else:
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_masterprojects_items(project_activity, category: int = None) -> list:
|
|
40
|
+
"""
|
|
41
|
+
Build the item list for masterprojects to be displayed in a select compoenent
|
|
42
|
+
|
|
43
|
+
:param project_activity: True if it is a project rather than a Hito activity
|
|
44
|
+
:param category: one of PROJECT_MGT_PROJECT_TYPE_xxx values or None. If None, menas
|
|
45
|
+
all active (non disabled) projects/activities
|
|
46
|
+
:return: list of projects/activities
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
if category == PROJECT_MGT_PROJECT_TYPE_LOCAL:
|
|
50
|
+
# Local projects have no masterproject
|
|
51
|
+
return []
|
|
52
|
+
|
|
53
|
+
activities = get_all_hito_activities(project_activity)
|
|
54
|
+
masterproject_items = []
|
|
55
|
+
if category == PROJECT_MGT_PROJECT_TYPE_DISABLED:
|
|
56
|
+
disabled = pd.DataFrame()
|
|
57
|
+
disabled[["masterproject_real", "project_real"]] = activities[
|
|
58
|
+
activities.masterproject == MASTERPROJECT_DELETED_ACTIVITY
|
|
59
|
+
]["project"].str.split(" / ", n=1, expand=True)
|
|
60
|
+
for masterproject in sorted(
|
|
61
|
+
disabled["masterproject_real"].unique(),
|
|
62
|
+
key=lambda x: x.upper(),
|
|
63
|
+
):
|
|
64
|
+
masterproject_items.append({"label": masterproject, "value": masterproject})
|
|
65
|
+
else:
|
|
66
|
+
masterproject_items = sorted(
|
|
67
|
+
activities[
|
|
68
|
+
(activities.masterproject != MASTERPROJECT_DELETED_ACTIVITY)
|
|
69
|
+
& (activities.masterproject != MASTERPROJECT_LOCAL_PROJECT)
|
|
70
|
+
]["masterproject"].unique(),
|
|
71
|
+
key=lambda x: x.upper(),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
return masterproject_items
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_projects_items(masterproject, project_activity, category: int = None) -> list:
|
|
78
|
+
"""
|
|
79
|
+
Build the item list for projects to be displayed in a select compoenent
|
|
80
|
+
|
|
81
|
+
:param masterproject: selected master project
|
|
82
|
+
:param project_activity: True if it is a project rather than a Hito activity
|
|
83
|
+
:param category: one of PROJECT_MGT_PROJECT_TYPE_xxx values or None. If None, menas
|
|
84
|
+
all active (non disabled) projects/activities
|
|
85
|
+
:return: list of projects/activities
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
if category == PROJECT_MGT_PROJECT_TYPE_LOCAL:
|
|
89
|
+
project_prefix = masterproject
|
|
90
|
+
masterproject = MASTERPROJECT_LOCAL_PROJECT
|
|
91
|
+
elif category == PROJECT_MGT_PROJECT_TYPE_DISABLED:
|
|
92
|
+
project_prefix = masterproject
|
|
93
|
+
masterproject = MASTERPROJECT_DELETED_ACTIVITY
|
|
94
|
+
else:
|
|
95
|
+
project_prefix = None
|
|
96
|
+
|
|
97
|
+
if masterproject:
|
|
98
|
+
activities = get_all_hito_activities(project_activity)
|
|
99
|
+
project_items = []
|
|
100
|
+
for project in sorted(
|
|
101
|
+
activities[activities.masterproject == masterproject]["project"].unique(),
|
|
102
|
+
key=lambda x: x.upper(),
|
|
103
|
+
):
|
|
104
|
+
if project_prefix is None or re.match(rf"{project_prefix}", project):
|
|
105
|
+
if category == PROJECT_MGT_PROJECT_TYPE_DISABLED:
|
|
106
|
+
project_name = project.split("/")[1]
|
|
107
|
+
else:
|
|
108
|
+
project_name = project
|
|
109
|
+
project_items.append({"label": project_name, "value": project})
|
|
110
|
+
return project_items
|
|
111
|
+
else:
|
|
112
|
+
return []
|