JoanGiner commited on
Commit
c032139
·
1 Parent(s): f9952ff

Changes in widgets for consistency. Added MArkdown generator with dummy functionality

Browse files
Files changed (2) hide show
  1. markdownGenerator.py +68 -0
  2. sdc_view.py +82 -79
markdownGenerator.py CHANGED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def generate_markdown(session_state):
2
+
3
+ html_str= f"""
4
+ # The Software diversity card of {session_state["master_title"]}
5
+ {session_state["master_desc"]}
6
+ ## 🏢 Teams Summary
7
+
8
+ <table>
9
+ <tr>
10
+ <th>Name</th>
11
+ <th>Type</th>
12
+ <th>Age Range</th>
13
+ <th>Ethnicities</th>
14
+ <th>Genders</th>
15
+ <th>Team Size</th>
16
+ <th>Average Tenure</th>
17
+ <th>Start Date</th>
18
+ <th>Location</th>
19
+ </tr>
20
+ <tr>
21
+ <td><strong>DevelopmentTeam</strong></td>
22
+ <td>DevelopmentTeam</td>
23
+ <td>25-30</td>
24
+ <td>Colombian, Brazilian, Argentinian, French, Spanish, Pakistani, Serbian, Iranian, Moroccan, Italian</td>
25
+ <td>Male 80%, Female 20%</td>
26
+ <td>15</td>
27
+ <td>4.3</td>
28
+ <td>11-08-2022</td>
29
+ <td>Luxembourg</td>
30
+ </tr>
31
+ <tr>
32
+ <td><strong>Usability Testers</strong></td>
33
+ <td>Tester Team</td>
34
+ <td>22-24</td>
35
+ <td>French</td>
36
+ <td>Non-disclosed</td>
37
+ <td>18</td>
38
+ <td>0.5</td>
39
+ <td>17-10-2023</td>
40
+ <td>University of Luxembourg</td>
41
+ </tr>
42
+ <tr>
43
+ <td><strong>Computer Science Students</strong></td>
44
+ <td>Target Community</td>
45
+ <td>18-100</td>
46
+ <td>Non-disclosed</td>
47
+ <td>Non-disclosed</td>
48
+ <td>-</td>
49
+ <td>0</td>
50
+ <td>-</td>
51
+ <td>France & Luxembourg</td>
52
+ </tr>
53
+ <tr>
54
+ <td><strong>Climate Public Servants</strong></td>
55
+ <td>Target Community</td>
56
+ <td>20-100</td>
57
+ <td>Non-disclosed</td>
58
+ <td>Non-disclosed</td>
59
+ <td>-</td>
60
+ <td>3-5</td>
61
+ <td>-</td>
62
+ <td>Luxembourg</td>
63
+ </tr>
64
+ </table>
65
+
66
+ ---
67
+ """
68
+ return html_str
sdc_view.py CHANGED
@@ -11,13 +11,14 @@ from markdownGenerator import *
11
 
12
  def render_sdc():
13
 
14
-
15
  EducationalLevelType = ['earlyChildhood','primary','lowerSecondary','upperSecondary','postSecondaryNonTertiary','shortCycleTertiary','bachelorEquivalent','masterEquivalent','doctorateEquivalent']
16
  SESType = ['upperClass' ,'upperMiddleClass' ,'middleClass' , 'lowerMiddleClass' , 'lowerClass']
17
  SkillLevelType = ['expert' , 'proficient' , 'advanced' , 'competent' , 'beginner']
18
  ISO3166 = ['Andorra', 'UnitedArabEmirates', 'Afghanistan', 'AntiguaandBarbuda', 'Anguilla', 'Albania', 'Armenia', 'Angola', 'Antarctica', 'Argentina', 'AmericanSamoa', 'Austria', 'Australia', 'Aruba', 'ÅlandIslands', 'Azerbaijan', 'BosniaandHerzegovina', 'Barbados', 'Bangladesh', 'Belgium', 'BurkinaFaso', 'Bulgaria', 'Bahrain', 'Burundi', 'Benin', 'SaintBarthélemy', 'Bermuda', 'BruneiDarussalam', 'Bolivia,PlurinationalStateof', 'Bonaire,SintEustatiusandSaba', 'Brazil', 'Bahamas', 'Bhutan', 'BouvetIsland', 'Botswana', 'Belarus', 'Belize', 'Canada', 'Cocos(Keeling)Islands', 'Congo,DemocraticRepublicofthe', 'CentralAfricanRepublic', 'Congo', 'Switzerland', 'CôtedIvoire', 'CookIslands', 'Chile', 'Cameroon', 'China', 'Colombia', 'CostaRica', 'Cuba', 'CaboVerde', 'Curaçao', 'ChristmasIsland', 'Cyprus', 'Czechia', 'Germany', 'Djibouti', 'Denmark', 'Dominica', 'DominicanRepublic', 'Algeria', 'Ecuador', 'Estonia', 'Egypt', 'WesternSahara', 'Eritrea', 'Spain', 'Ethiopia', 'Finland', 'Fiji', 'FalklandIslands(Malvinas)', 'Micronesia,FederatedStatesof', 'FaroeIslands', 'France', 'Gabon', 'UnitedKingdomofGreatBritainandNorthernIreland', 'Grenada', 'Georgia', 'FrenchGuiana', 'Guernsey', 'Ghana', 'Gibraltar', 'Greenland', 'Gambia', 'Guinea', 'Guadeloupe', 'EquatorialGuinea', 'Greece', 'SouthGeorgiaandtheSouthSandwichIslands', 'Guatemala', 'Guam', 'Guinea-Bissau', 'Guyana', 'HongKong', 'HeardIslandandMcDonaldIslands', 'Honduras', 'Croatia', 'Haiti', 'Hungary', 'Indonesia', 'Ireland', 'Israel', 'IsleofMan', 'India', 'BritishIndianOceanTerritory', 'Iraq', 'Iran,IslamicRepublicof', 'Iceland', 'Italy', 'Jersey', 'Jamaica', 'Jordan', 'Japan', 'Kenya', 'Kyrgyzstan', 'Cambodia', 'Kiribati', 'Comoros', 'SaintKittsandNevis', 'Korea,DemocraticPeoplesRepublicof', 'Korea,Republicof', 'Kuwait', 'CaymanIslands', 'Kazakhstan', 'LaoPeoplesDemocraticRepublic', 'Lebanon', 'SaintLucia', 'Liechtenstein', 'SriLanka', 'Liberia', 'Lesotho', 'Lithuania', 'Luxembourg', 'Latvia', 'Libya', 'Morocco', 'Monaco', 'Moldova,Republicof', 'Montenegro', 'SaintMartin(Frenchpart)', 'Madagascar', 'MarshallIslands', 'NorthMacedonia', 'Mali', 'Myanmar', 'Mongolia', 'Macao', 'NorthernMarianaIslands', 'Martinique', 'Mauritania', 'Montserrat', 'Malta', 'Mauritius', 'Maldives', 'Malawi', 'Mexico', 'Malaysia', 'Mozambique', 'Namibia', 'NewCaledonia', 'Niger', 'NorfolkIsland', 'Nigeria', 'Nicaragua', 'Netherlands,Kingdomofthe', 'Norway', 'Nepal', 'Nauru', 'Niue', 'NewZealand', 'Oman', 'Panama', 'Peru', 'FrenchPolynesia', 'PapuaNewGuinea', 'Philippines', 'Pakistan', 'Poland', 'SaintPierreandMiquelon', 'Pitcairn', 'PuertoRico', 'Palestine,Stateof', 'Portugal', 'Palau', 'Paraguay', 'Qatar', 'Réunion', 'Romania', 'Serbia', 'RussianFederation', 'Rwanda', 'SaudiArabia', 'SolomonIslands', 'Seychelles', 'Sudan', 'Sweden', 'Singapore', 'SaintHelena,AscensionandTristandaCunha', 'Slovenia', 'SvalbardandJanMayen', 'Slovakia', 'SierraLeone', 'SanMarino', 'Senegal', 'Somalia', 'Suriname', 'SouthSudan', 'SaoTomeandPrincipe', 'ElSalvador', 'SintMaarten(Dutchpart)', 'SyrianArabRepublic', 'Eswatini', 'TurksandCaicosIslands', 'Chad', 'FrenchSouthernTerritories', 'Togo', 'Thailand', 'Tajikistan', 'Tokelau', 'Timor-Leste', 'Turkmenistan', 'Tunisia', 'Tonga', 'Türkiye', 'TrinidadandTobago', 'Tuvalu', 'Taiwan,ProvinceofChina', 'Tanzania,UnitedRepublicof', 'Ukraine', 'Uganda', 'UnitedStatesMinorOutlyingIslands', 'UnitedStatesofAmerica', 'Uruguay', 'Uzbekistan', 'HolySee', 'SaintVincentandtheGrenadines', 'Venezuela,BolivarianRepublicof', 'VirginIslands(British)', 'VirginIslands(U.S.)', 'VietNam', 'Vanuatu', 'WallisandFutuna', 'Samoa', 'Yemen', 'Mayotte', 'SouthAfrica', 'Zambia', 'Zimbabwe']
19
  ISO639 = ['Afar' , 'Abkhazian', 'Avestan' , 'Afrikaans' , 'Akan' , 'Amharic' , 'Aragonese','Arabic','Assamese','Avaric','Aymara','Azerbaijani','Bashkir','Belarusian','Bulgarian','Bislama','Bambara','Bengali','Tibetan','Breton','Bosnian','Catalan-Valencian','Chechen','Chamorro','Corsican','Cree','Czech','ChurchSlavonic-OldSlavonic-OldChurchSlavonic','Chuvash','Welsh','Danish','German','Divehi-Dhivehi-Maldivian','Dzongkha','Ewe','GreekModern','English','Esperanto','Spanish-Castilian','Estonian','Basque','Persian','Fulah','Finnish','Fijian','Faroese','French','WesternFrisian','Irish','Gaelic-ScottishGaelic','Galician','Guarani','Gujarati','Manx','Hausa','Hebrew','Hindi','HiriMotu','Croatian','Haitian-HaitianCreole','Hungarian','Armenian','Herero','Interlingua','Indonesian','Interlingue-Occidental','Igbo','SichuanYi-Nuosu','Inupiaq','Ido','Icelandic','Italian','Inuktitut','Japanese','Javanese','Georgian','Kongo','Kikuyu-Gikuyu','Kuanyama-Kwanyama','Kazakh','Kalaallisut-Greenlandic','CentralKhmer','Kannada','Korean','Kanuri','Kashmiri','Kurdish','Komi','Cornish','Kyrgyz-Kirghiz','Latin','Luxembourgish-Letzeburgesch','Ganda','Limburgan-Limburger-Limburgish','Lingala','Lao','Lithuanian','Luba-Katanga','Latvian','Malagasy','Marshallese','Maori','Macedonian','Malayalam','Mongolian','Marathi','Malay','Maltese','Burmese','Nauru','NorwegianBokmål','NorthNdebele','Nepali','Ndonga','Dutch-Flemish','NorwegianNynorsk','Norwegian','SouthNdebele','Navajo-Navaho','Chichewa-Chewa-Nyanja','Occitan','Ojibwa','Oromo','Oriya','Ossetian-Ossetic','Punjabi-Panjabi','Pali','Polish','Pashto-Pushto','Portuguese','Quechua','Romansh','Rundi','Romanian-Moldavian-Moldovan','Russian','Kinyarwanda','Sanskrit','Sardinian','Sindhi','NorthernSami','Sango','Sinhala-Sinhalese','Slovak','Slovenian','Samoan','Shona','Somali','Albanian','Serbian','Swati','SouthernSotho','Sundanese','Swedish','Swahili','Tamil','Telugu','Tajik','Thai','Tigrinya','Turkmen','Tagalog','Tswana','Tonga','Turkish','Tsonga','Tatar','Twi','Tahitian','Uighur-Uyghur','Ukrainian','Urdu','Uzbek','Venda','Vietnamese','Volapük','Walloon','Wolof','Xhosa','Yiddish','Yoruba','Zhuang-Chuang','Chinese','Zulu']
20
 
 
21
  STATE_FILE = "session_state.json"
22
 
23
  def load_state():
@@ -27,6 +28,7 @@ def render_sdc():
27
  with open(STATE_FILE, "r") as f:
28
  data = json.load(f)
29
  st.session_state.update(data)
 
30
  except Exception as e:
31
  st.error(f"Error loading state: {e}")
32
 
@@ -35,7 +37,7 @@ def render_sdc():
35
  try:
36
  # Convert session_state to a regular dict before dumping
37
  with open(STATE_FILE, "w") as f:
38
- json.dump(dict(st.session_state), f)
39
  except Exception as e:
40
  st.error(f"Error saving state: {e}")
41
 
@@ -68,11 +70,6 @@ def render_sdc():
68
  st.cache_data.clear()
69
  st.cache_data(lambda: st.session_state.form_data) # Save updated form data
70
 
71
- # Function to save input into cache
72
- def save_to_cache():
73
- st.cache_data.clear() # Clear old cache before saving
74
- st.cache_data(lambda: st.session_state) # Save updated state
75
-
76
  # Function to create a text area with caching
77
  def cached_text_area(label, key, placeholder=""):
78
  if key not in st.session_state.form_data:
@@ -102,9 +99,9 @@ def render_sdc():
102
  save_state()
103
  # Function to create a text area with caching
104
  def cached_radio_input(label, options, key, help=""):
105
- if key not in st.session_state.form_data:
106
- st.session_state.form_data[key] = "" # Initialize dynamically
107
-
108
  st.radio(
109
  label=label,
110
  options=options,
@@ -121,15 +118,49 @@ def render_sdc():
121
  # Initialize session state for selected countries if needed
122
  if key not in st.session_state:
123
  st.session_state[key] = []
 
 
 
 
124
  # Display the multiselect widget
125
  st.multiselect(
126
  label,
127
  options=options,
 
128
  key=key,
129
  on_change=lambda: (st.session_state.form_data.update({key: st.session_state[key]}), save_to_cache())[1]
130
  )
131
 
132
- # Function to create a text area with caching
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  def participant(key):
134
  colr, coll = st.columns([1, 1])
135
  with colr:
@@ -142,7 +173,7 @@ def render_sdc():
142
  st.number_input(
143
  label="The age of the participant:",
144
  key=agekey,
145
- on_change=lambda: (st.session_state.form_data.update({key: st.session_state[key]}), save_to_cache())[1]
146
  )
147
  cached_text_input("Location", f"{key}_location", "The title of the card")
148
  cached_radio_input("WorkplaceType", ["Presential", "Hybrid", "Remote"], f"{key}_workdplace", "The title of the card")
@@ -176,43 +207,14 @@ def render_sdc():
176
  group(key)
177
 
178
  def team(key):
179
- #cached_text_input("Team name", f"{key}_name", "Name or identifier of the team")
180
- #cached_text_area("Team description", f"{key}_desc", "Description of the team")
181
- agesize = f"{key}_size"
182
- if agesize not in st.session_state:
183
- st.session_state[agesize] = 0 # default value
184
- # Display a number input widget
185
- st.slider(
186
- label="The number of participants in the team:",
187
- min_value=0,
188
- max_value=120,
189
- value=(10,20),
190
- key=agesize,
191
- on_change=lambda: (st.session_state.form_data.update({key: st.session_state[agesize]}), save_to_cache())[1]
192
- )
193
- colr, coll = st.columns([1, 1])
194
- with colr:
195
- st.date_input(label="Start date of the team", value=datetime.date(2019, 7, 6),key=f"{key}_startdate",on_change=lambda: (st.session_state.form_data.update({key: st.session_state[f"{key}_startdate"]}), save_to_cache())[1])
196
- with coll:
197
- st.date_input(label="End date of the team", value=datetime.date(2019, 7, 6),key=f"{key}_enddate",on_change=lambda: (st.session_state.form_data.update({key: st.session_state[f"{key}_enddate"]}), save_to_cache())[1])
198
-
199
  group(key)
200
 
201
  def group(key):
202
  colr, coll = st.columns([1, 1])
203
  with colr:
204
- agekey = f"{key}_age"
205
- if agekey not in st.session_state:
206
- st.session_state[agekey] = 0 # default value
207
- # Display a number input widget
208
- st.slider(
209
- label="The average age of the participant:",
210
- min_value=0,
211
- max_value=120,
212
- value=(10,20),
213
- key=agekey,
214
- on_change=lambda: (st.session_state.form_data.update({key: st.session_state[agekey]}), save_to_cache())[1]
215
- )
216
  cached_text_input("Location", f"{key}_location", "Location of the organization")
217
  cached_radio_input("WorkplaceType", ["Presential", "Hybrid", "Remote"], f"{key}_workplace", "The kind of organization")
218
  cached_text_input("Ethnicities", f"{key}_ethnicities", "Ethinicities present in the organization, comma sepparated ")
@@ -224,7 +226,7 @@ def render_sdc():
224
  cached_multiple_radio(f"{key}_edlevel",EducationalLevelType,"Educational Level")
225
  cached_multiple_radio( f"{key}_sociostati", SESType,"Socioeconomic Status")
226
  cached_multiple_radio( f"{key}_skills", SkillLevelType,"Skill Level")
227
- cached_multiple_radio( f"{key}_languages", ISO3166, "Select one or several langauges spoken by the participant:")
228
  # Initialize session state for the number input if it doesn't exist
229
  agekey = f"{key}_tenure"
230
  if agekey not in st.session_state:
@@ -234,7 +236,7 @@ def render_sdc():
234
  st.number_input(
235
  label="The professioanl tenure of the participant in years",
236
  key=agekey,
237
- on_change=lambda: (st.session_state.form_data.update({key: st.session_state[key]}), save_to_cache())[1]
238
  )
239
 
240
  def init_state(key):
@@ -310,7 +312,7 @@ def render_sdc():
310
  unsafe_allow_html=True
311
  )
312
  st.markdown("""\
313
- Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
314
  """)
315
 
316
 
@@ -322,7 +324,8 @@ def render_sdc():
322
  cached_text_area("A description of the software project", "master_desc", "The title of the card")
323
 
324
 
325
- with st.expander("**Document the teams and crowds in your software**", expanded=True):
 
326
  governance, usageContext, participants = st.tabs([
327
  "Governance",
328
  "Usage context",
@@ -339,16 +342,18 @@ def render_sdc():
339
  key = "governance_govProcesses"
340
  init_state(key)
341
  st.write("Define the set of governament process of your software project")
 
342
  if st.button("Add governament processes"):
343
  add_text_area(key)
344
  # Loop over the array and create a text area with a remove button for each element
345
- for idx, text in enumerate(st.session_state[key]):
346
  # Create two columns: one for the text area, one for the remove button
347
  col1, col2 = st.columns([6, 1])
348
  with col1:
349
  cached_text_area(f"Governament process {idx + 1}", f"governance_govProcesses{idx}", "Specific the governance rules of the software project. For instance, the funders, or the role and the relation between the different bodies that governs the software.")
350
  with col2:
351
- if st.button("Remove", key=f"{key}_remove_{idx}"):
 
352
  remove_text_area(idx,key)
353
 
354
  # BODIES
@@ -370,21 +375,20 @@ def render_sdc():
370
 
371
  with col2:
372
  if st.button("Remove", key=f"{key}_remove_{idx}"):
373
- remove_text_area(idx,key)
374
  cached_multiple_radio(f"{key}_{idx}_type", ['funders', 'directors', 'administrators', 'other'], f"Body role type" )
375
 
376
- st.text("If participants in the body are individuals please use the individuals tab. If not, leave it blank.")
377
- # Button to add a new text area
378
- org, individual = st.tabs([
379
- "Organization",
380
- "Individual",
381
- ])
382
- with individual:
383
- participant(f"{key}_{idx}_participant")
384
- with org:
385
- organization(f"{key}_{idx}_organization")
386
 
387
-
388
  with usageContext:
389
  colr, coll = st.columns([1, 1])
390
  with colr:
@@ -392,7 +396,7 @@ def render_sdc():
392
  cached_text_area("Social context",f"{key}_description", "Description of the usage and social context of the app")
393
  with coll:
394
  cached_multiple_radio(f"{key}_countries",ISO3166,"The countries where the app is intended to be deployed and used")
395
- cached_multiple_radio( f"{key}_languages", ISO3166, "The relevant languages for the app usage's context")
396
  targetCommunities, adaptations = st.tabs([
397
  "Targeted Communities",
398
  "Adpatations",
@@ -406,9 +410,7 @@ def render_sdc():
406
  with adaptations:
407
  keyAdapt = key+"_adaptation"
408
  cached_text_input("Name",f"{keyAdapt}_name", "Name or ID of the adaptation")
409
- cached_text_area("Description",f"{keyAdapt}_description", "Description of the adaptation")
410
-
411
-
412
 
413
  with participants:
414
  # Participants
@@ -430,38 +432,39 @@ def render_sdc():
430
 
431
  with col2:
432
  if st.button("Remove", key=f"{key}_remove_{idx}"):
433
- remove_text_area(idx,key)
434
  cached_multiple_radio(f"{key}_{idx}_type", ['Development Team', 'NonCoding Contributor', 'Tester Team', 'Public Reporter TEam'], f"Team role type" )
435
  team(f"{key}_{idx}")
436
 
437
 
438
-
439
-
440
-
441
  ## Showing the generated card and the generated JSON
442
  st.divider()
443
- promptTab, impTab = st.tabs(["**Compiled card in markdown**", "**Generated JSON**" ])
444
- with promptTab:
445
- html_str= generate_markdown(st.session_state)
446
-
447
  # Provide a download button
448
  st.download_button(
449
  label="Download Markdown",
450
- data=html_str,
451
  file_name="SoftareDiveristyCard.md",
452
  mime="text/markdown"
453
  )
454
- st.markdown(html_str, unsafe_allow_html=True)
455
- with impTab:
 
456
 
457
  # Convert the session state to a JSON string
458
  session_state_json = json.dumps(serialize_session_state(), indent=4)
459
  st.download_button(
460
  label="Download JSON",
461
  data=session_state_json,
462
- file_name="SoftareDiveristyCard.json",
463
  mime="application/json"
464
  )
465
  # Display the session state as pretty JSON
466
- st.json(serialize_session_state())
 
 
467
 
 
11
 
12
  def render_sdc():
13
 
14
+ ## Constant of the Software diversity card
15
  EducationalLevelType = ['earlyChildhood','primary','lowerSecondary','upperSecondary','postSecondaryNonTertiary','shortCycleTertiary','bachelorEquivalent','masterEquivalent','doctorateEquivalent']
16
  SESType = ['upperClass' ,'upperMiddleClass' ,'middleClass' , 'lowerMiddleClass' , 'lowerClass']
17
  SkillLevelType = ['expert' , 'proficient' , 'advanced' , 'competent' , 'beginner']
18
  ISO3166 = ['Andorra', 'UnitedArabEmirates', 'Afghanistan', 'AntiguaandBarbuda', 'Anguilla', 'Albania', 'Armenia', 'Angola', 'Antarctica', 'Argentina', 'AmericanSamoa', 'Austria', 'Australia', 'Aruba', 'ÅlandIslands', 'Azerbaijan', 'BosniaandHerzegovina', 'Barbados', 'Bangladesh', 'Belgium', 'BurkinaFaso', 'Bulgaria', 'Bahrain', 'Burundi', 'Benin', 'SaintBarthélemy', 'Bermuda', 'BruneiDarussalam', 'Bolivia,PlurinationalStateof', 'Bonaire,SintEustatiusandSaba', 'Brazil', 'Bahamas', 'Bhutan', 'BouvetIsland', 'Botswana', 'Belarus', 'Belize', 'Canada', 'Cocos(Keeling)Islands', 'Congo,DemocraticRepublicofthe', 'CentralAfricanRepublic', 'Congo', 'Switzerland', 'CôtedIvoire', 'CookIslands', 'Chile', 'Cameroon', 'China', 'Colombia', 'CostaRica', 'Cuba', 'CaboVerde', 'Curaçao', 'ChristmasIsland', 'Cyprus', 'Czechia', 'Germany', 'Djibouti', 'Denmark', 'Dominica', 'DominicanRepublic', 'Algeria', 'Ecuador', 'Estonia', 'Egypt', 'WesternSahara', 'Eritrea', 'Spain', 'Ethiopia', 'Finland', 'Fiji', 'FalklandIslands(Malvinas)', 'Micronesia,FederatedStatesof', 'FaroeIslands', 'France', 'Gabon', 'UnitedKingdomofGreatBritainandNorthernIreland', 'Grenada', 'Georgia', 'FrenchGuiana', 'Guernsey', 'Ghana', 'Gibraltar', 'Greenland', 'Gambia', 'Guinea', 'Guadeloupe', 'EquatorialGuinea', 'Greece', 'SouthGeorgiaandtheSouthSandwichIslands', 'Guatemala', 'Guam', 'Guinea-Bissau', 'Guyana', 'HongKong', 'HeardIslandandMcDonaldIslands', 'Honduras', 'Croatia', 'Haiti', 'Hungary', 'Indonesia', 'Ireland', 'Israel', 'IsleofMan', 'India', 'BritishIndianOceanTerritory', 'Iraq', 'Iran,IslamicRepublicof', 'Iceland', 'Italy', 'Jersey', 'Jamaica', 'Jordan', 'Japan', 'Kenya', 'Kyrgyzstan', 'Cambodia', 'Kiribati', 'Comoros', 'SaintKittsandNevis', 'Korea,DemocraticPeoplesRepublicof', 'Korea,Republicof', 'Kuwait', 'CaymanIslands', 'Kazakhstan', 'LaoPeoplesDemocraticRepublic', 'Lebanon', 'SaintLucia', 'Liechtenstein', 'SriLanka', 'Liberia', 'Lesotho', 'Lithuania', 'Luxembourg', 'Latvia', 'Libya', 'Morocco', 'Monaco', 'Moldova,Republicof', 'Montenegro', 'SaintMartin(Frenchpart)', 'Madagascar', 'MarshallIslands', 'NorthMacedonia', 'Mali', 'Myanmar', 'Mongolia', 'Macao', 'NorthernMarianaIslands', 'Martinique', 'Mauritania', 'Montserrat', 'Malta', 'Mauritius', 'Maldives', 'Malawi', 'Mexico', 'Malaysia', 'Mozambique', 'Namibia', 'NewCaledonia', 'Niger', 'NorfolkIsland', 'Nigeria', 'Nicaragua', 'Netherlands,Kingdomofthe', 'Norway', 'Nepal', 'Nauru', 'Niue', 'NewZealand', 'Oman', 'Panama', 'Peru', 'FrenchPolynesia', 'PapuaNewGuinea', 'Philippines', 'Pakistan', 'Poland', 'SaintPierreandMiquelon', 'Pitcairn', 'PuertoRico', 'Palestine,Stateof', 'Portugal', 'Palau', 'Paraguay', 'Qatar', 'Réunion', 'Romania', 'Serbia', 'RussianFederation', 'Rwanda', 'SaudiArabia', 'SolomonIslands', 'Seychelles', 'Sudan', 'Sweden', 'Singapore', 'SaintHelena,AscensionandTristandaCunha', 'Slovenia', 'SvalbardandJanMayen', 'Slovakia', 'SierraLeone', 'SanMarino', 'Senegal', 'Somalia', 'Suriname', 'SouthSudan', 'SaoTomeandPrincipe', 'ElSalvador', 'SintMaarten(Dutchpart)', 'SyrianArabRepublic', 'Eswatini', 'TurksandCaicosIslands', 'Chad', 'FrenchSouthernTerritories', 'Togo', 'Thailand', 'Tajikistan', 'Tokelau', 'Timor-Leste', 'Turkmenistan', 'Tunisia', 'Tonga', 'Türkiye', 'TrinidadandTobago', 'Tuvalu', 'Taiwan,ProvinceofChina', 'Tanzania,UnitedRepublicof', 'Ukraine', 'Uganda', 'UnitedStatesMinorOutlyingIslands', 'UnitedStatesofAmerica', 'Uruguay', 'Uzbekistan', 'HolySee', 'SaintVincentandtheGrenadines', 'Venezuela,BolivarianRepublicof', 'VirginIslands(British)', 'VirginIslands(U.S.)', 'VietNam', 'Vanuatu', 'WallisandFutuna', 'Samoa', 'Yemen', 'Mayotte', 'SouthAfrica', 'Zambia', 'Zimbabwe']
19
  ISO639 = ['Afar' , 'Abkhazian', 'Avestan' , 'Afrikaans' , 'Akan' , 'Amharic' , 'Aragonese','Arabic','Assamese','Avaric','Aymara','Azerbaijani','Bashkir','Belarusian','Bulgarian','Bislama','Bambara','Bengali','Tibetan','Breton','Bosnian','Catalan-Valencian','Chechen','Chamorro','Corsican','Cree','Czech','ChurchSlavonic-OldSlavonic-OldChurchSlavonic','Chuvash','Welsh','Danish','German','Divehi-Dhivehi-Maldivian','Dzongkha','Ewe','GreekModern','English','Esperanto','Spanish-Castilian','Estonian','Basque','Persian','Fulah','Finnish','Fijian','Faroese','French','WesternFrisian','Irish','Gaelic-ScottishGaelic','Galician','Guarani','Gujarati','Manx','Hausa','Hebrew','Hindi','HiriMotu','Croatian','Haitian-HaitianCreole','Hungarian','Armenian','Herero','Interlingua','Indonesian','Interlingue-Occidental','Igbo','SichuanYi-Nuosu','Inupiaq','Ido','Icelandic','Italian','Inuktitut','Japanese','Javanese','Georgian','Kongo','Kikuyu-Gikuyu','Kuanyama-Kwanyama','Kazakh','Kalaallisut-Greenlandic','CentralKhmer','Kannada','Korean','Kanuri','Kashmiri','Kurdish','Komi','Cornish','Kyrgyz-Kirghiz','Latin','Luxembourgish-Letzeburgesch','Ganda','Limburgan-Limburger-Limburgish','Lingala','Lao','Lithuanian','Luba-Katanga','Latvian','Malagasy','Marshallese','Maori','Macedonian','Malayalam','Mongolian','Marathi','Malay','Maltese','Burmese','Nauru','NorwegianBokmål','NorthNdebele','Nepali','Ndonga','Dutch-Flemish','NorwegianNynorsk','Norwegian','SouthNdebele','Navajo-Navaho','Chichewa-Chewa-Nyanja','Occitan','Ojibwa','Oromo','Oriya','Ossetian-Ossetic','Punjabi-Panjabi','Pali','Polish','Pashto-Pushto','Portuguese','Quechua','Romansh','Rundi','Romanian-Moldavian-Moldovan','Russian','Kinyarwanda','Sanskrit','Sardinian','Sindhi','NorthernSami','Sango','Sinhala-Sinhalese','Slovak','Slovenian','Samoan','Shona','Somali','Albanian','Serbian','Swati','SouthernSotho','Sundanese','Swedish','Swahili','Tamil','Telugu','Tajik','Thai','Tigrinya','Turkmen','Tagalog','Tswana','Tonga','Turkish','Tsonga','Tatar','Twi','Tahitian','Uighur-Uyghur','Ukrainian','Urdu','Uzbek','Venda','Vietnamese','Volapük','Walloon','Wolof','Xhosa','Yiddish','Yoruba','Zhuang-Chuang','Chinese','Zulu']
20
 
21
+ ## The file where the state is
22
  STATE_FILE = "session_state.json"
23
 
24
  def load_state():
 
28
  with open(STATE_FILE, "r") as f:
29
  data = json.load(f)
30
  st.session_state.update(data)
31
+ st.session_state['form_data'] = data
32
  except Exception as e:
33
  st.error(f"Error loading state: {e}")
34
 
 
37
  try:
38
  # Convert session_state to a regular dict before dumping
39
  with open(STATE_FILE, "w") as f:
40
+ json.dump(dict(st.session_state['form_data']), f)
41
  except Exception as e:
42
  st.error(f"Error saving state: {e}")
43
 
 
70
  st.cache_data.clear()
71
  st.cache_data(lambda: st.session_state.form_data) # Save updated form data
72
 
 
 
 
 
 
73
  # Function to create a text area with caching
74
  def cached_text_area(label, key, placeholder=""):
75
  if key not in st.session_state.form_data:
 
99
  save_state()
100
  # Function to create a text area with caching
101
  def cached_radio_input(label, options, key, help=""):
102
+ if key not in st.session_state.form_data or st.session_state.form_data[key] not in options:
103
+ st.session_state.form_data[key] = options[0] # Initialize dynamically
104
+
105
  st.radio(
106
  label=label,
107
  options=options,
 
118
  # Initialize session state for selected countries if needed
119
  if key not in st.session_state:
120
  st.session_state[key] = []
121
+ default = []
122
+ else:
123
+ default = st.session_state[key]
124
+
125
  # Display the multiselect widget
126
  st.multiselect(
127
  label,
128
  options=options,
129
+ default=default,
130
  key=key,
131
  on_change=lambda: (st.session_state.form_data.update({key: st.session_state[key]}), save_to_cache())[1]
132
  )
133
 
134
+ def cached_range_input(key, value, label ):
135
+
136
+ if key not in st.session_state.form_data:
137
+ st.session_state.form_data[key] = value # Initialize dynamically
138
+ else:
139
+ st.session_state[key] = st.session_state.form_data[key]
140
+ # Display a number input widget
141
+ st.slider(
142
+ label=label,
143
+ min_value=0,
144
+ max_value=120,
145
+ value=value,
146
+ key=key,
147
+ on_change=lambda: (st.session_state.form_data.update({key: st.session_state[key]}), save_to_cache())[1]
148
+ )
149
+ save_state()
150
+
151
+ def cached_date_input(label, key):
152
+
153
+ if key not in st.session_state:
154
+ st.session_state[key] = []
155
+
156
+ st.date_input(
157
+ label=label,
158
+ value=datetime.date(2019, 7, 6),
159
+ key=key,
160
+ on_change=lambda: (st.session_state.form_data.update({key: st.session_state[f"{key}_startdate"]}), save_to_cache())[1]
161
+ )
162
+
163
+
164
  def participant(key):
165
  colr, coll = st.columns([1, 1])
166
  with colr:
 
173
  st.number_input(
174
  label="The age of the participant:",
175
  key=agekey,
176
+ on_change=lambda: (st.session_state.form_data.update({key: st.session_state[agekey]}), save_to_cache())[1]
177
  )
178
  cached_text_input("Location", f"{key}_location", "The title of the card")
179
  cached_radio_input("WorkplaceType", ["Presential", "Hybrid", "Remote"], f"{key}_workdplace", "The title of the card")
 
207
  group(key)
208
 
209
  def team(key):
210
+ cached_range_input(f"{key}_size", 0, "The size of the group")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  group(key)
212
 
213
  def group(key):
214
  colr, coll = st.columns([1, 1])
215
  with colr:
216
+
217
+ cached_range_input(f"{key}_age",(10,20), "The age range of the participants")
 
 
 
 
 
 
 
 
 
 
218
  cached_text_input("Location", f"{key}_location", "Location of the organization")
219
  cached_radio_input("WorkplaceType", ["Presential", "Hybrid", "Remote"], f"{key}_workplace", "The kind of organization")
220
  cached_text_input("Ethnicities", f"{key}_ethnicities", "Ethinicities present in the organization, comma sepparated ")
 
226
  cached_multiple_radio(f"{key}_edlevel",EducationalLevelType,"Educational Level")
227
  cached_multiple_radio( f"{key}_sociostati", SESType,"Socioeconomic Status")
228
  cached_multiple_radio( f"{key}_skills", SkillLevelType,"Skill Level")
229
+ cached_multiple_radio( f"{key}_languages", ISO639, "Select one or several langauges spoken by the participant:")
230
  # Initialize session state for the number input if it doesn't exist
231
  agekey = f"{key}_tenure"
232
  if agekey not in st.session_state:
 
236
  st.number_input(
237
  label="The professioanl tenure of the participant in years",
238
  key=agekey,
239
+ on_change=lambda: (st.session_state.form_data.update({key: st.session_state[agekey]}), save_to_cache())[1]
240
  )
241
 
242
  def init_state(key):
 
312
  unsafe_allow_html=True
313
  )
314
  st.markdown("""\
315
+ Welcome to the Software Diversity Card Generator—a form-based application designed to empower you to highlight and promote diversity in software projects. Our innovative tool helps you generate comprehensive diversity cards in both JSON and Markdown formats, offering a transparent overview of the varied teams involved in development and governance, the user groups engaged in testing, and the tailored software adaptations for different social groups. By providing a structured model, an extended JSON syntax, and a toolkit backed by real-world examples, our platform aims to foster inclusive practices that can be embraced by open-source communities, academic journals, and forward-thinking businesses alike.
316
  """)
317
 
318
 
 
324
  cached_text_area("A description of the software project", "master_desc", "The title of the card")
325
 
326
 
327
+ with st.container( border=True):
328
+ st.subheader("Describe the different teams in the software project")
329
  governance, usageContext, participants = st.tabs([
330
  "Governance",
331
  "Usage context",
 
342
  key = "governance_govProcesses"
343
  init_state(key)
344
  st.write("Define the set of governament process of your software project")
345
+
346
  if st.button("Add governament processes"):
347
  add_text_area(key)
348
  # Loop over the array and create a text area with a remove button for each element
349
+ for idx, processes in enumerate(st.session_state[key]):
350
  # Create two columns: one for the text area, one for the remove button
351
  col1, col2 = st.columns([6, 1])
352
  with col1:
353
  cached_text_area(f"Governament process {idx + 1}", f"governance_govProcesses{idx}", "Specific the governance rules of the software project. For instance, the funders, or the role and the relation between the different bodies that governs the software.")
354
  with col2:
355
+ # print(st.session_state['governance_govProcesses_remove_0'])
356
+ if st.button("Remove", key=f"remove_{key}_{idx}"):
357
  remove_text_area(idx,key)
358
 
359
  # BODIES
 
375
 
376
  with col2:
377
  if st.button("Remove", key=f"{key}_remove_{idx}"):
378
+ remove_text_area(idx,f"{key}_remove_{idx}")
379
  cached_multiple_radio(f"{key}_{idx}_type", ['funders', 'directors', 'administrators', 'other'], f"Body role type" )
380
 
381
+ with st.expander("If needed provide detailed information about the organizations or individuals involved in the governance", expanded=False):
382
+ # Button to add a new text area
383
+ org, individual = st.tabs([
384
+ "Organization",
385
+ "Individual",
386
+ ])
387
+ with individual:
388
+ participant(f"{key}_{idx}_participant")
389
+ with org:
390
+ organization(f"{key}_{idx}_organization")
391
 
 
392
  with usageContext:
393
  colr, coll = st.columns([1, 1])
394
  with colr:
 
396
  cached_text_area("Social context",f"{key}_description", "Description of the usage and social context of the app")
397
  with coll:
398
  cached_multiple_radio(f"{key}_countries",ISO3166,"The countries where the app is intended to be deployed and used")
399
+ cached_multiple_radio( f"{key}_languages", ISO639, "The relevant languages for the app usage's context")
400
  targetCommunities, adaptations = st.tabs([
401
  "Targeted Communities",
402
  "Adpatations",
 
410
  with adaptations:
411
  keyAdapt = key+"_adaptation"
412
  cached_text_input("Name",f"{keyAdapt}_name", "Name or ID of the adaptation")
413
+ cached_text_area("Description",f"{keyAdapt}_description", "Description of the adaptation")
 
 
414
 
415
  with participants:
416
  # Participants
 
432
 
433
  with col2:
434
  if st.button("Remove", key=f"{key}_remove_{idx}"):
435
+ remove_text_area(idx,f"{key}_remove_{idx}")
436
  cached_multiple_radio(f"{key}_{idx}_type", ['Development Team', 'NonCoding Contributor', 'Tester Team', 'Public Reporter TEam'], f"Team role type" )
437
  team(f"{key}_{idx}")
438
 
439
 
440
+
 
 
441
  ## Showing the generated card and the generated JSON
442
  st.divider()
443
+ st.subheader("The generated card")
444
+ markDownTab, jsonTab = st.tabs(["**Compiled card in markdown**", "**Generated JSON**" ])
445
+ with markDownTab:
446
+
447
  # Provide a download button
448
  st.download_button(
449
  label="Download Markdown",
450
+ data=generate_markdown(st.session_state),
451
  file_name="SoftareDiveristyCard.md",
452
  mime="text/markdown"
453
  )
454
+ st.text("Preview:")
455
+ st.markdown(generate_markdown(st.session_state), unsafe_allow_html=True)
456
+ with jsonTab:
457
 
458
  # Convert the session state to a JSON string
459
  session_state_json = json.dumps(serialize_session_state(), indent=4)
460
  st.download_button(
461
  label="Download JSON",
462
  data=session_state_json,
463
+ file_name=f"{st.session_state["master_title"]}_diveristy_card.json",
464
  mime="application/json"
465
  )
466
  # Display the session state as pretty JSON
467
+ #st.json(serialize_session_state())
468
+ st.text("Preview:")
469
+ st.json(st.session_state["form_data"])
470