solara 0.2.0 → 0.2.2

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.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/solara/lib/core/.DS_Store +0 -0
  3. data/solara/lib/core/aliases/alias_generator.rb +1 -0
  4. data/solara/lib/core/aliases/alias_generator_manager.rb +2 -1
  5. data/solara/lib/core/aliases/solara_terminal_setup.rb +1 -1
  6. data/solara/lib/core/brands/brand_font_switcher.rb +154 -0
  7. data/solara/lib/core/brands/brand_onboarder.rb +8 -6
  8. data/solara/lib/core/brands/brand_switcher.rb +232 -166
  9. data/solara/lib/core/brands/brands_manager.rb +15 -39
  10. data/solara/lib/core/dashboard/brand/BrandDetail.js +19 -0
  11. data/solara/lib/core/dashboard/brand/BrandDetailController.js +50 -8
  12. data/solara/lib/core/dashboard/brand/BrandDetailModel.js +9 -30
  13. data/solara/lib/core/dashboard/brand/BrandDetailView.js +49 -3
  14. data/solara/lib/core/dashboard/brand/InfoPlistStringCatalogManager.js +19 -0
  15. data/solara/lib/core/dashboard/brand/brand.html +209 -62
  16. data/solara/lib/core/dashboard/brand/source/BrandLocalSource.js +1 -1
  17. data/solara/lib/core/dashboard/brand/source/BrandRemoteSource.js +38 -53
  18. data/solara/lib/core/dashboard/brands/BrandsController.js +6 -5
  19. data/solara/lib/core/dashboard/brands/BrandsModel.js +2 -2
  20. data/solara/lib/core/dashboard/brands/BrandsView.js +2 -2
  21. data/solara/lib/core/dashboard/brands/brands.html +3 -1
  22. data/solara/lib/core/dashboard/component/AliasesBottomSheet.js +7 -5
  23. data/solara/lib/core/dashboard/dashboard_manager.rb +2 -0
  24. data/solara/lib/core/dashboard/dashboard_server.rb +13 -8
  25. data/solara/lib/core/dashboard/handler/brand_alisases_handler.rb +4 -11
  26. data/solara/lib/core/dashboard/handler/brand_configurations_manager.rb +11 -11
  27. data/solara/lib/core/dashboard/handler/{brand_configurations_handler.rb → brand_details_handler.rb} +4 -4
  28. data/solara/lib/core/dashboard/handler/brands_handler.rb +1 -1
  29. data/solara/lib/core/dashboard/handler/edit_section_handler.rb +8 -8
  30. data/solara/lib/core/doctor/brand_doctor.rb +31 -31
  31. data/solara/lib/core/doctor/doctor_manager.rb +0 -1
  32. data/solara/lib/core/doctor/project_doctor.rb +0 -1
  33. data/solara/lib/core/doctor/schema/platform/android/android_config.json +0 -4
  34. data/solara/lib/core/doctor/schema/platform/ios/InfoPlist.xcstrings +15 -0
  35. data/solara/lib/core/doctor/schema/platform/ios/ios_config.json +0 -5
  36. data/solara/lib/core/doctor/schema/platform/shared/brand_config.json +9 -0
  37. data/solara/lib/core/doctor/schema/platform/shared/theme.json +94 -9
  38. data/solara/lib/core/doctor/validator/brand_settings_validator.rb +6 -0
  39. data/solara/lib/core/doctor/validator/brand_settings_validator_manager.rb +9 -21
  40. data/solara/lib/core/doctor/validator/template/android_template_validation_config.yml +22 -4
  41. data/solara/lib/core/doctor/validator/template/flutter_template_validation_config.yml +22 -6
  42. data/solara/lib/core/doctor/validator/template/ios_template_validation_config.yml +22 -4
  43. data/solara/lib/core/scripts/brand_config_generator.rb +1 -0
  44. data/solara/lib/core/scripts/brand_config_manager.rb +2 -4
  45. data/solara/lib/core/scripts/brand_exporter.rb +1 -1
  46. data/solara/lib/core/scripts/brand_importer.rb +2 -3
  47. data/solara/lib/core/scripts/brand_offboarder.rb +5 -0
  48. data/solara/lib/core/scripts/brand_resources_manager.rb +127 -54
  49. data/solara/lib/core/scripts/directory_creator.rb +2 -2
  50. data/solara/lib/core/scripts/file_manager.rb +53 -19
  51. data/solara/lib/core/scripts/file_path.rb +175 -30
  52. data/solara/lib/core/scripts/folder_copier.rb +3 -7
  53. data/solara/lib/core/scripts/gitignore_manager.rb +21 -10
  54. data/solara/lib/core/scripts/interactive_file_system_validator.rb +8 -2
  55. data/solara/lib/core/scripts/platform/android/android_manifest_switcher.rb +3 -3
  56. data/solara/lib/core/scripts/platform/android/android_strings_switcher.rb +26 -24
  57. data/solara/lib/core/scripts/platform/android/gradle_switcher.rb +7 -6
  58. data/solara/lib/core/scripts/platform/ios/infoplist_string_catalog_manager.rb +123 -0
  59. data/solara/lib/core/scripts/platform/ios/infoplist_switcher.rb +59 -0
  60. data/solara/lib/core/scripts/platform/ios/ios_plist_manager.rb +11 -20
  61. data/solara/lib/core/scripts/platform/ios/plist_font_manager.rb +33 -0
  62. data/solara/lib/core/scripts/platform/ios/xcconfig_generator.rb +15 -3
  63. data/solara/lib/core/scripts/platform/ios/xcode_asset_manager.rb +2 -3
  64. data/solara/lib/core/scripts/platform/ios/xcode_project_manager.rb +80 -1
  65. data/solara/lib/core/scripts/platform/ios/xcode_project_switcher.rb +15 -34
  66. data/solara/lib/core/scripts/solara_logger.rb +10 -0
  67. data/solara/lib/core/scripts/solara_settings_manager.rb +26 -1
  68. data/solara/lib/core/scripts/strings_xml_manager.rb +17 -2
  69. data/solara/lib/core/scripts/theme_generator.rb +133 -130
  70. data/solara/lib/core/scripts/yaml_manager.rb +23 -0
  71. data/solara/lib/core/solara_configurator.rb +1 -1
  72. data/solara/lib/core/template/brands/android/android_config.json +0 -1
  73. data/solara/lib/core/template/brands/android/res/values/strings.xml +4 -0
  74. data/solara/lib/core/template/brands/ios/InfoPlist.xcstrings +30 -0
  75. data/solara/lib/core/template/brands/ios/ios_config.json +1 -2
  76. data/solara/lib/core/template/brands/shared/brand_config.json +1 -0
  77. data/solara/lib/core/template/brands/shared/theme.json +3 -3
  78. data/solara/lib/core/template/config/android_template_config.json +11 -1
  79. data/solara/lib/core/template/config/flutter_template_config.json +12 -2
  80. data/solara/lib/core/template/config/ios_template_config.json +11 -1
  81. data/solara/lib/core/template/project_template_generator.rb +8 -3
  82. data/solara/lib/solara/version.rb +1 -1
  83. data/solara/lib/solara.rb +8 -4
  84. data/solara/lib/solara_initializer.rb +5 -2
  85. data/solara/lib/solara_manager.rb +1 -1
  86. metadata +62 -43
  87. data/solara/lib/core/dashboard/handler/brand_section_handler.rb +0 -20
  88. data/solara/lib/core/doctor/validator/directory_structure_validator.rb +0 -38
  89. data/solara/lib/core/doctor/validator/file_structure_validator.rb +0 -37
  90. data/solara/lib/core/scripts/platform/ios/ios_file_path_manager.rb +0 -109
  91. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/.DS_Store +0 -0
  92. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/100.png +0 -0
  93. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/102.png +0 -0
  94. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/1024.png +0 -0
  95. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/114.png +0 -0
  96. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/120.png +0 -0
  97. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/128.png +0 -0
  98. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/144.png +0 -0
  99. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/152.png +0 -0
  100. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/16.png +0 -0
  101. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/167.png +0 -0
  102. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/172.png +0 -0
  103. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/180.png +0 -0
  104. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/196.png +0 -0
  105. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/20.png +0 -0
  106. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/216.png +0 -0
  107. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/256.png +0 -0
  108. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/29.png +0 -0
  109. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/32.png +0 -0
  110. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/40.png +0 -0
  111. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/48.png +0 -0
  112. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/50.png +0 -0
  113. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/512.png +0 -0
  114. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/55.png +0 -0
  115. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/57.png +0 -0
  116. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/58.png +0 -0
  117. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/60.png +0 -0
  118. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/64.png +0 -0
  119. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/66.png +0 -0
  120. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/72.png +0 -0
  121. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/76.png +0 -0
  122. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/80.png +0 -0
  123. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/87.png +0 -0
  124. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/88.png +0 -0
  125. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/92.png +0 -0
  126. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/Contents.json +0 -0
@@ -25,6 +25,75 @@
25
25
  padding-top: 110px;
26
26
  }
27
27
  .container {
28
+ display: table;
29
+ width: 100%;
30
+ height: 100vh;
31
+ }
32
+ .row {
33
+ display: table-row;
34
+ }
35
+ .column {
36
+ display: table-cell;
37
+ padding: 20px;
38
+ vertical-align: top;
39
+ }
40
+ .left {
41
+ position: fixed;
42
+ width: 20%;
43
+ }
44
+ .middle {
45
+ width: 60%;
46
+ background-color: #e0e0e0;
47
+ }
48
+ .right {
49
+ position: fixed;
50
+ width: 20%;
51
+ max-height: 600px; /* Set a fixed height */
52
+ overflow-y: auto; /* Enable vertical scrolling */
53
+ padding: 10px; /* Optional: add padding */
54
+ }
55
+ ul {
56
+ list-style-type: none;
57
+ padding: 0;
58
+ }
59
+ li {
60
+ margin-bottom: 10px;
61
+ }
62
+
63
+ .index {
64
+ list-style-type: none; /* Remove default list styling */
65
+ padding: 0; /* Remove padding */
66
+ margin: 40px;
67
+ }
68
+ .index li {
69
+ padding: 8px; /* Add some padding to list items */
70
+ border-bottom: 1px solid #eee; /* Optional: add a bottom border */
71
+ }
72
+
73
+ .index li:last-child {
74
+ border-bottom: none; /* Remove the border from the last item */
75
+ }
76
+ .index a {
77
+ color: #0066cc;
78
+ text-decoration: none;
79
+ }
80
+ .index a:hover {
81
+ text-decoration: underline;
82
+ }
83
+ .index-item {
84
+ list-style: none; /* Remove default list styling */
85
+ padding: 10px; /* Add some padding */
86
+ margin: 5px 0; /* Space between items */
87
+ background-color: white; /* Background color for contrast */
88
+ border-radius: 5px; /* Rounded corners */
89
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); /* Shadow effect */
90
+ transition: box-shadow 0.3s; /* Smooth transition for shadow */
91
+ }
92
+
93
+ .index-item:hover {
94
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); /* Darker shadow on hover */
95
+ }
96
+ .sections {
28
97
  max-width: 1000px;
29
98
  margin: 0 auto;
30
99
  padding: 20px;
@@ -60,6 +129,21 @@
60
129
  .input-group:hover {
61
130
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
62
131
  }
132
+ .input-wrapper {
133
+ display: flex;
134
+ align-items: center;
135
+ flex-grow: 1;
136
+ }
137
+ .input-wrapper input[type="checkbox"] {
138
+ margin-right: 10px;
139
+ flex-grow: 0;
140
+ }
141
+ .checkbox-label {
142
+ flex-grow: 1;
143
+ }
144
+ .input-wrapper label[for] {
145
+ margin-right: 10px;
146
+ }
63
147
  label {
64
148
  display: inline-block;
65
149
  margin-right: 10px;
@@ -67,11 +151,6 @@
67
151
  min-width: 250px;
68
152
  flex-shrink: 0;
69
153
  }
70
- .input-wrapper {
71
- display: flex;
72
- align-items: center;
73
- flex-grow: 1;
74
- }
75
154
  input, select {
76
155
  flex-grow: 1;
77
156
  padding: 10px;
@@ -138,7 +217,7 @@
138
217
  }
139
218
 
140
219
  @media (max-width: 768px) {
141
- .container {
220
+ .sections {
142
221
  padding: 10px;
143
222
  }
144
223
  .input-group {
@@ -214,6 +293,18 @@
214
293
  display: flex;
215
294
  align-items: center;
216
295
  justify-content: center;
296
+ transition: transform 0.3s ease;
297
+ transform: translateY(0);
298
+ z-index: 1000;
299
+ }
300
+ .scroll-down {
301
+ transform: translateY(-100%);
302
+ }
303
+
304
+ .header-content {
305
+ display: flex;
306
+ align-items: center;
307
+ justify-content: center;
217
308
  }
218
309
 
219
310
  header {
@@ -238,39 +329,35 @@
238
329
  .scroll-down header {
239
330
  transform: translateY(-100%);
240
331
  }
241
- .logo {
242
- width: 50px;
243
- height: 50px;
244
- margin-right: 20px;
245
- filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.3));
246
- transition: transform 0.3s ease;
247
- }
248
- .logo:hover {
249
- transform: scale(1.1);
250
- }
332
+
251
333
  h1 {
252
334
  margin: 0;
253
335
  font-size: 2.5em;
254
336
  }
255
337
 
256
338
  .action-buttons {
257
- position: fixed;
258
- top: 100px;
259
- left: 20px;
260
- display: flex;
261
- flex-direction: column;
262
- gap: 20px;
263
- z-index: 1000;
339
+ min-width: 250px;
340
+ background-color: var(--primary-color);
341
+ color: white;
342
+ margin: 10px;
343
+ font-size: 18px;
344
+ transition: background-color 0.3s ease, opacity 0.3s ease;
264
345
  }
265
346
 
266
- .action-buttons button {
267
- min-width: 250px;
347
+ .add-field-btn {
348
+ min-width: 150px;
268
349
  background-color: var(--primary-color);
269
350
  color: white;
270
- padding: 12px 10px;
271
- border: none;
272
- border-radius: 4px;
273
- cursor: pointer;
351
+ margin: 10px;
352
+ font-size: 18px;
353
+ transition: background-color 0.3s ease, opacity 0.3s ease;
354
+ }
355
+
356
+ .apply-changes-button {
357
+ min-width: 250px;
358
+ background-color: #ff4136;
359
+ color: white;
360
+ margin: 10px;
274
361
  font-size: 18px;
275
362
  transition: background-color 0.3s ease, opacity 0.3s ease;
276
363
  }
@@ -287,7 +374,6 @@
287
374
  display: none;
288
375
  }
289
376
 
290
-
291
377
  #error-button {
292
378
  position: fixed;
293
379
  bottom: 20px;
@@ -305,6 +391,7 @@
305
391
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
306
392
  transition: transform 0.2s;
307
393
  display: none;
394
+ z-index: 1000;
308
395
  }
309
396
 
310
397
  #error-button:hover {
@@ -327,7 +414,20 @@
327
414
  align-items: center;
328
415
  }
329
416
 
417
+ .add-brand-overlay {
418
+ display: none;
419
+ position: fixed;
420
+ top: 0;
421
+ left: 0;
422
+ width: 100%;
423
+ height: 100%;
424
+ color: white;
425
+ background-color: black;
426
+ z-index: 998;
427
+ }
428
+
330
429
  .add-brand-container {
430
+ display: none;
331
431
  position: fixed;
332
432
  top: 50%;
333
433
  left: 50%;
@@ -341,6 +441,7 @@
341
441
  animation: fadeIn 0.5s ease-out;
342
442
  }
343
443
 
444
+
344
445
  @keyframes fadeIn {
345
446
  from {
346
447
  opacity: 0;
@@ -417,60 +518,106 @@
417
518
  }
418
519
  }
419
520
 
420
-
421
- /* Hide the brand-details-container by default */
422
521
  #brand-details-container {
423
522
  display: none;
424
523
  }
524
+ #add-brand-container {
525
+ display: none;
526
+ }
527
+
528
+ .loading-overlay {
529
+ position: fixed;
530
+ top: 0;
531
+ left: 0;
532
+ width: 100%;
533
+ height: 100%;
534
+ background-color: black;
535
+ display: flex;
536
+ align-items: center;
537
+ justify-content: center;
538
+ z-index: 9999;
539
+ }
540
+
541
+ .loading-overlay-logo {
542
+ width: 150px;
543
+ height: 150px;
544
+ margin-right: 20px;
545
+ filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.3));
546
+ transition: transform 0.3s ease;
547
+ }
425
548
  </style>
426
549
  </head>
427
550
  <body>
428
551
 
429
- <header>
430
- <div class="header-container">
552
+ <header id="header" class="header-container">
553
+ <div class="header-content">
431
554
  <img class="logo" src="../solara.png" alt="Splash Image">
432
555
  <h1><span id="brandNametitle"></span></h1>
433
556
  </div>
434
557
 
435
558
  </header>
436
559
 
437
- <div id="add-brand-container" class="add-brand-container">
438
- <img src="../solara.png" alt="Solara Logo">
439
- <h2>Solara simplifies the management of your brand configurations, allowing you to access and update them anytime, anywhere.</h2>
440
- <div class="button-message">You can select a JSON file containing brand configurations that were exported using Solara.</div>
441
- <button id="uploadJsonBtn" style=" animation-delay: 0.5s;">Upload JSON</button>
442
- <div class="button-message" style=" animation-delay: 0.7s;">Alternatively, upload from a folder that includes the brand's JSON files.</div>
443
- <button id="uploadBrandBtn" style=" animation-delay: 0.9s;">Upload Folder</button>
444
- <div class="button-message" style=" animation-delay: 1.1s;">You also have the option to create new brand configurations.</div>
445
- <button id="newBrandBtn" style=" animation-delay: 1.3s;">New Brand</button>
560
+ <div class="loading-overlay" id="loadingOverlay">
561
+ <img class="loading-overlay-logo" src="../solara.png" alt="Loading Logo">
446
562
  </div>
447
563
 
448
- <onboard-bottom-sheet id="onboardBottomSheet"></onboard-bottom-sheet>
564
+ <div class="container">
565
+ <div class="row">
449
566
 
450
- <div id="brand-details-container">
451
- <button id="error-button">
452
- ⚠️
453
- <span class="count">5</span>
454
- </button>
455
-
456
- <div class="action-buttons">
457
- <button id="allBrandsButton">All Brands</button>
458
- <button id="switchButton">Switch</button>
459
- <button id="applyChangesButton">Apply Changes</button>
460
- <button id="exportBrandBtn">Export</button>
461
- </div>
567
+ <div class="column left">
568
+ <div>
569
+ <button id="allBrandsButton" class="action-buttons">All Brands</button>
570
+ <button id="switchButton" class="action-buttons">Switch</button>
571
+ <button id="applyChangesButton" class="apply-changes-button">Apply Changes</button>
572
+ <button id="exportBrandBtn" class="action-buttons">Export</button>
573
+ </div>
574
+ </div>
462
575
 
463
- <div class="container">
464
- <div id="sections"></div>
465
- </div>
576
+ <div class="column middle">
577
+
578
+ <div id="brand-details-container">
579
+ <button id="error-button">
580
+ ⚠️
581
+ <span class="count">5</span>
582
+ </button>
583
+
584
+ <div class="sections">
585
+ <div id="sections"></div>
586
+ </div>
587
+ </div>
588
+
589
+ <div class="add-brand-overlay" id="add-brand-overlay"></div>
590
+
591
+ <div id="add-brand-container" class="add-brand-container">
592
+ <img src="../solara.png" alt="Solara Logo">
593
+ <h2>Solara simplifies the management of your brand configurations, allowing you to access and update them anytime, anywhere.</h2>
594
+ <div class="button-message">You can select a JSON file containing brand configurations that were exported using Solara.</div>
595
+ <button id="uploadJsonBtn" style=" animation-delay: 0.5s;">Upload JSON</button>
596
+ <div class="button-message" style=" animation-delay: 0.7s;">Alternatively, upload from a folder that includes the brand's JSON files.</div>
597
+ <button id="uploadBrandBtn" style=" animation-delay: 0.9s;">Upload Folder</button>
598
+ <div class="button-message" style=" animation-delay: 1.1s;">You also have the option to create new brand configurations.</div>
599
+ <button id="newBrandBtn" style=" animation-delay: 1.3s;">New Brand</button>
600
+ </div>
466
601
 
467
- <add-field-sheet id="addFieldSheet"></add-field-sheet>
602
+ </div>
468
603
 
469
- <message-bottom-sheet id="messageBottomSheet"></message-bottom-sheet>
470
604
 
471
- <confirmation-dialog id="confirmationDialog"></confirmation-dialog>
605
+ <div class="column right">
606
+ <ul id="index" class="index">
607
+ </ul>
608
+ </div>
609
+
610
+ </div>
472
611
  </div>
473
612
 
613
+ <onboard-bottom-sheet id="onboardBottomSheet"></onboard-bottom-sheet>
614
+
615
+ <add-field-sheet id="addFieldSheet"></add-field-sheet>
616
+
617
+ <message-bottom-sheet id="messageBottomSheet"></message-bottom-sheet>
618
+
619
+ <confirmation-dialog id="confirmationDialog"></confirmation-dialog>
620
+
474
621
  <script type="module" src="BrandDetail.js"></script>
475
622
 
476
623
  </body>
@@ -14,7 +14,7 @@ class BrandLocalSource {
14
14
  throw new Error('No brand_key provided in URL');
15
15
  }
16
16
 
17
- const url = `/configurations?brand_key=${encodeURIComponent(brandKey)}`;
17
+ const url = `/brand/details?brand_key=${encodeURIComponent(brandKey)}`;
18
18
  console.log('Fetching configurations from:', url);
19
19
 
20
20
  const response = await fetch(url);
@@ -4,31 +4,11 @@ class BrandRemoteSource {
4
4
  constructor() {
5
5
  }
6
6
 
7
- async fetchBrandDetails(brandKey) {
8
-
9
- }
10
-
11
- async fetchCurrentBrand(brandKey) {
12
- // Empty for now
13
- }
14
-
15
- async saveSection(sectionItem, configuration, brandKey) {
16
- // Empty for now
17
- }
18
-
19
- async switchToBrand(brandKey) {
20
- // Empty for now
21
- }
22
-
23
- async checkBrandHealth(brandKey) {
24
- // Empty for now
25
- }
26
-
27
7
  async createNewBrandConfogurations() {
28
8
  const configurations_template = `
29
9
  [
30
10
  {
31
- "key": "theme",
11
+ "key": "theme.json",
32
12
  "name": "Theme Configuration",
33
13
  "inputType": "color",
34
14
  "content": {
@@ -46,9 +26,9 @@ class BrandRemoteSource {
46
26
  },
47
27
  "typography": {
48
28
  "fontFamily": {
49
- "regular": "Roboto",
50
- "medium": "Roboto-Medium",
51
- "bold": "Roboto-Bold"
29
+ "regular": "",
30
+ "medium": "",
31
+ "bold": ""
52
32
  },
53
33
  "fontSize": {
54
34
  "small": 12,
@@ -77,17 +57,16 @@ class BrandRemoteSource {
77
57
  }
78
58
  },
79
59
  {
80
- "key": "brand_config",
60
+ "key": "brand_config.json",
81
61
  "name": "Brand Configuration",
82
62
  "inputType": "text",
83
63
  "content": {}
84
64
  },
85
65
  {
86
- "key": "android_config",
66
+ "key": "android_config.json",
87
67
  "name": "Android Platform Configuration",
88
68
  "inputType": "text",
89
69
  "content": {
90
- "brandName": "",
91
70
  "applicationId": "",
92
71
  "versionName": "1.0.0",
93
72
  "versionCode": 1,
@@ -95,7 +74,7 @@ class BrandRemoteSource {
95
74
  }
96
75
  },
97
76
  {
98
- "key": "android_signing",
77
+ "key": "android_signing.json",
99
78
  "name": "Android Signing",
100
79
  "inputType": "text",
101
80
  "content": {
@@ -106,19 +85,30 @@ class BrandRemoteSource {
106
85
  }
107
86
  },
108
87
  {
109
- "key": "ios_config",
88
+ "key": "ios_config.json",
110
89
  "name": "iOS Platform Configuration",
111
90
  "inputType": "text",
112
91
  "content": {
113
- "PRODUCT_NAME": "",
114
92
  "PRODUCT_BUNDLE_IDENTIFIER": "",
115
93
  "MARKETING_VERSION": "1.0.0",
116
- "BUNDLE_VERSION": "1",
94
+ "BUNDLE_VERSION": 1,
117
95
  "APL_MRCH_ID": ""
118
96
  }
119
97
  },
120
98
  {
121
- "key": "ios_signing",
99
+ "key": "ios_signing.json",
100
+ "name": "iOS Signing",
101
+ "inputType": "text",
102
+ "content": {
103
+ "CODE_SIGN_IDENTITY": "",
104
+ "DEVELOPMENT_TEAM": "",
105
+ "PROVISIONING_PROFILE_SPECIFIER": "",
106
+ "CODE_SIGN_STYLE": "Automatic",
107
+ "CODE_SIGN_ENTITLEMENTS": ""
108
+ }
109
+ },
110
+ {
111
+ "key": "ios_signing.json",
122
112
  "name": "iOS Signing",
123
113
  "inputType": "text",
124
114
  "content": {
@@ -129,7 +119,8 @@ class BrandRemoteSource {
129
119
  "CODE_SIGN_ENTITLEMENTS": ""
130
120
  }
131
121
  }
132
- ]`;
122
+ ]
123
+ `;
133
124
  return JSON.parse(configurations_template);
134
125
  }
135
126
 
@@ -183,46 +174,40 @@ class BrandRemoteSource {
183
174
  const configList = [];
184
175
  const expectedFiles = [
185
176
  {
186
- key: 'theme',
177
+ key: 'theme.json',
187
178
  name: 'Theme Configuration',
188
- input_type: 'color',
189
- filename: 'theme.json'
179
+ input_type: 'color'
190
180
  },
191
181
  {
192
- key: 'brand_config',
182
+ key: 'brand_config.json',
193
183
  name: 'Brand Configuration',
194
- input_type: 'text',
195
- filename: 'brand_config.json'
184
+ input_type: 'text'
196
185
  },
197
186
  {
198
- key: 'android_config',
187
+ key: 'android_config.json',
199
188
  name: 'Android Platform Configuration',
200
- input_type: 'text',
201
- filename: 'android_config.json'
189
+ input_type: 'text'
202
190
  },
203
191
  {
204
- key: 'android_signing',
192
+ key: 'android_signing.json',
205
193
  name: 'Android Signing',
206
- input_type: 'text',
207
- filename: 'android_signing.json'
194
+ input_type: 'text'
208
195
  },
209
196
  {
210
- key: 'ios_config',
197
+ key: 'ios_config.json',
211
198
  name: 'iOS Platform Configuration',
212
- input_type: 'text',
213
- filename: 'ios_config.json'
199
+ input_type: 'text'
214
200
  },
215
201
  {
216
- key: 'ios_signing',
202
+ key: 'ios_signing.json',
217
203
  name: 'iOS Signing',
218
- input_type: 'text',
219
- filename: 'ios_signing.json'
204
+ input_type: 'text'
220
205
  }
221
206
  ];
222
207
 
223
208
  for (const file of expectedFiles) {
224
209
  try {
225
- const fileContent = await this.findAndReadFile(dirHandle, file.filename);
210
+ const fileContent = await this.findAndReadFile(dirHandle, file.key);
226
211
  if (fileContent) {
227
212
  configList.push({
228
213
  key: file.key,
@@ -232,7 +217,7 @@ class BrandRemoteSource {
232
217
  });
233
218
  }
234
219
  } catch (error) {
235
- console.warn(`File not found or invalid JSON: ${file.filename}`);
220
+ console.warn(`File not found or invalid JSON: ${file.key}`);
236
221
  }
237
222
  }
238
223
 
@@ -49,18 +49,18 @@ class BrandsController {
49
49
  });
50
50
  }
51
51
 
52
- showOnboardBrandForm() {
52
+ showOnboardBrandForm(clone_brand_key = null) {
53
53
  this.view.showOnboardBrandForm();
54
54
  this.view.onboardSheet.addEventListener('onboard', async (event) => {
55
55
  event.preventDefault();
56
56
  const {brandKey, brandName} = event.detail;
57
- await this.handleOnboardBrandSubmit(brandKey, brandName);
57
+ await this.handleOnboardBrandSubmit(brandKey, brandName, clone_brand_key);
58
58
  });
59
59
  }
60
60
 
61
- async handleOnboardBrandSubmit(brandKey, brandName) {
61
+ async handleOnboardBrandSubmit(brandKey, brandName, clone_brand_key = null) {
62
62
  try {
63
- await this.model.onboardBrand(brandName, brandKey);
63
+ await this.model.onboardBrand(brandName, brandKey, clone_brand_key);
64
64
  await this.view.hideOnboardBrandForm();
65
65
  location.reload();
66
66
  } catch (error) {
@@ -95,7 +95,8 @@ class BrandsController {
95
95
 
96
96
  handleCloneOption(event) {
97
97
  event.stopPropagation();
98
- this.showOnboardBrandForm();
98
+ const brandKey = this.view.brandOptionsSheet.dataset.brandKey;
99
+ this.showOnboardBrandForm(brandKey);
99
100
  }
100
101
 
101
102
  handleOffboardOption(event) {
@@ -27,7 +27,7 @@ class BrandsModel {
27
27
 
28
28
  async fetchBrands() {
29
29
  try {
30
- const response = await fetch('/brands.json');
30
+ const response = await fetch('/brands/all');
31
31
  const result = await response.json();
32
32
  if (!response.ok) {
33
33
  throw new Error(result.error);
@@ -42,7 +42,7 @@ class BrandsModel {
42
42
 
43
43
  async fetchAliases(brand) {
44
44
  try {
45
- const response = await fetch(`/brand/aliases?brand_key=${brand.key}`);
45
+ const response = await fetch(`/brand/aliases`);
46
46
  let result = await response.json();
47
47
  if (!response.ok) {
48
48
  throw new Error(result.error);
@@ -90,9 +90,9 @@ class BrandsView {
90
90
  this.onboardSheet.hide();
91
91
  }
92
92
 
93
- showAliasesBottomSheet(aliases, brand) {
93
+ showAliasesBottomSheet(aliases, brandKey) {
94
94
  const aliasesSheet = document.getElementById('aliasesSheet');
95
- aliasesSheet.show(aliases, brand);
95
+ aliasesSheet.show(aliases, brandKey);
96
96
  }
97
97
 
98
98
  showBrandOptionsSheet(brand) {
@@ -97,6 +97,7 @@
97
97
  font-size: 16px;
98
98
  transition: background-color 0.3s ease;
99
99
  margin-right: 15px;
100
+ min-width: 130px;
100
101
  }
101
102
  .switch-button:hover {
102
103
  background-color: #3a7bc8;
@@ -146,6 +147,7 @@
146
147
  cursor: pointer;
147
148
  font-size: 16px;
148
149
  transition: background-color 0.3s ease;
150
+ min-width: 130px;
149
151
  }
150
152
  .onboard-brand-button:hover {
151
153
  background-color: #3a7bc8;
@@ -309,7 +311,7 @@
309
311
  </button>
310
312
 
311
313
  <div class="container">
312
- <div class="current-brand" id="currentBrandSection" style=" display: none;">
314
+ <div class="current-brand" id="currentBrandSection" style="display: none;">
313
315
  <h2>Current Brand</h2>
314
316
  <div id="currentBrandItem"></div>
315
317
  </div>