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.
- checksums.yaml +4 -4
- data/solara/lib/core/.DS_Store +0 -0
- data/solara/lib/core/aliases/alias_generator.rb +1 -0
- data/solara/lib/core/aliases/alias_generator_manager.rb +2 -1
- data/solara/lib/core/aliases/solara_terminal_setup.rb +1 -1
- data/solara/lib/core/brands/brand_font_switcher.rb +154 -0
- data/solara/lib/core/brands/brand_onboarder.rb +8 -6
- data/solara/lib/core/brands/brand_switcher.rb +232 -166
- data/solara/lib/core/brands/brands_manager.rb +15 -39
- data/solara/lib/core/dashboard/brand/BrandDetail.js +19 -0
- data/solara/lib/core/dashboard/brand/BrandDetailController.js +50 -8
- data/solara/lib/core/dashboard/brand/BrandDetailModel.js +9 -30
- data/solara/lib/core/dashboard/brand/BrandDetailView.js +49 -3
- data/solara/lib/core/dashboard/brand/InfoPlistStringCatalogManager.js +19 -0
- data/solara/lib/core/dashboard/brand/brand.html +209 -62
- data/solara/lib/core/dashboard/brand/source/BrandLocalSource.js +1 -1
- data/solara/lib/core/dashboard/brand/source/BrandRemoteSource.js +38 -53
- data/solara/lib/core/dashboard/brands/BrandsController.js +6 -5
- data/solara/lib/core/dashboard/brands/BrandsModel.js +2 -2
- data/solara/lib/core/dashboard/brands/BrandsView.js +2 -2
- data/solara/lib/core/dashboard/brands/brands.html +3 -1
- data/solara/lib/core/dashboard/component/AliasesBottomSheet.js +7 -5
- data/solara/lib/core/dashboard/dashboard_manager.rb +2 -0
- data/solara/lib/core/dashboard/dashboard_server.rb +13 -8
- data/solara/lib/core/dashboard/handler/brand_alisases_handler.rb +4 -11
- data/solara/lib/core/dashboard/handler/brand_configurations_manager.rb +11 -11
- data/solara/lib/core/dashboard/handler/{brand_configurations_handler.rb → brand_details_handler.rb} +4 -4
- data/solara/lib/core/dashboard/handler/brands_handler.rb +1 -1
- data/solara/lib/core/dashboard/handler/edit_section_handler.rb +8 -8
- data/solara/lib/core/doctor/brand_doctor.rb +31 -31
- data/solara/lib/core/doctor/doctor_manager.rb +0 -1
- data/solara/lib/core/doctor/project_doctor.rb +0 -1
- data/solara/lib/core/doctor/schema/platform/android/android_config.json +0 -4
- data/solara/lib/core/doctor/schema/platform/ios/InfoPlist.xcstrings +15 -0
- data/solara/lib/core/doctor/schema/platform/ios/ios_config.json +0 -5
- data/solara/lib/core/doctor/schema/platform/shared/brand_config.json +9 -0
- data/solara/lib/core/doctor/schema/platform/shared/theme.json +94 -9
- data/solara/lib/core/doctor/validator/brand_settings_validator.rb +6 -0
- data/solara/lib/core/doctor/validator/brand_settings_validator_manager.rb +9 -21
- data/solara/lib/core/doctor/validator/template/android_template_validation_config.yml +22 -4
- data/solara/lib/core/doctor/validator/template/flutter_template_validation_config.yml +22 -6
- data/solara/lib/core/doctor/validator/template/ios_template_validation_config.yml +22 -4
- data/solara/lib/core/scripts/brand_config_generator.rb +1 -0
- data/solara/lib/core/scripts/brand_config_manager.rb +2 -4
- data/solara/lib/core/scripts/brand_exporter.rb +1 -1
- data/solara/lib/core/scripts/brand_importer.rb +2 -3
- data/solara/lib/core/scripts/brand_offboarder.rb +5 -0
- data/solara/lib/core/scripts/brand_resources_manager.rb +127 -54
- data/solara/lib/core/scripts/directory_creator.rb +2 -2
- data/solara/lib/core/scripts/file_manager.rb +53 -19
- data/solara/lib/core/scripts/file_path.rb +175 -30
- data/solara/lib/core/scripts/folder_copier.rb +3 -7
- data/solara/lib/core/scripts/gitignore_manager.rb +21 -10
- data/solara/lib/core/scripts/interactive_file_system_validator.rb +8 -2
- data/solara/lib/core/scripts/platform/android/android_manifest_switcher.rb +3 -3
- data/solara/lib/core/scripts/platform/android/android_strings_switcher.rb +26 -24
- data/solara/lib/core/scripts/platform/android/gradle_switcher.rb +7 -6
- data/solara/lib/core/scripts/platform/ios/infoplist_string_catalog_manager.rb +123 -0
- data/solara/lib/core/scripts/platform/ios/infoplist_switcher.rb +59 -0
- data/solara/lib/core/scripts/platform/ios/ios_plist_manager.rb +11 -20
- data/solara/lib/core/scripts/platform/ios/plist_font_manager.rb +33 -0
- data/solara/lib/core/scripts/platform/ios/xcconfig_generator.rb +15 -3
- data/solara/lib/core/scripts/platform/ios/xcode_asset_manager.rb +2 -3
- data/solara/lib/core/scripts/platform/ios/xcode_project_manager.rb +80 -1
- data/solara/lib/core/scripts/platform/ios/xcode_project_switcher.rb +15 -34
- data/solara/lib/core/scripts/solara_logger.rb +10 -0
- data/solara/lib/core/scripts/solara_settings_manager.rb +26 -1
- data/solara/lib/core/scripts/strings_xml_manager.rb +17 -2
- data/solara/lib/core/scripts/theme_generator.rb +133 -130
- data/solara/lib/core/scripts/yaml_manager.rb +23 -0
- data/solara/lib/core/solara_configurator.rb +1 -1
- data/solara/lib/core/template/brands/android/android_config.json +0 -1
- data/solara/lib/core/template/brands/android/res/values/strings.xml +4 -0
- data/solara/lib/core/template/brands/ios/InfoPlist.xcstrings +30 -0
- data/solara/lib/core/template/brands/ios/ios_config.json +1 -2
- data/solara/lib/core/template/brands/shared/brand_config.json +1 -0
- data/solara/lib/core/template/brands/shared/theme.json +3 -3
- data/solara/lib/core/template/config/android_template_config.json +11 -1
- data/solara/lib/core/template/config/flutter_template_config.json +12 -2
- data/solara/lib/core/template/config/ios_template_config.json +11 -1
- data/solara/lib/core/template/project_template_generator.rb +8 -3
- data/solara/lib/solara/version.rb +1 -1
- data/solara/lib/solara.rb +8 -4
- data/solara/lib/solara_initializer.rb +5 -2
- data/solara/lib/solara_manager.rb +1 -1
- metadata +62 -43
- data/solara/lib/core/dashboard/handler/brand_section_handler.rb +0 -20
- data/solara/lib/core/doctor/validator/directory_structure_validator.rb +0 -38
- data/solara/lib/core/doctor/validator/file_structure_validator.rb +0 -37
- data/solara/lib/core/scripts/platform/ios/ios_file_path_manager.rb +0 -109
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/.DS_Store +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/100.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/102.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/1024.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/114.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/120.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/128.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/144.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/152.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/16.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/167.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/172.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/180.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/196.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/20.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/216.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/256.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/29.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/32.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/40.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/48.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/50.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/512.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/55.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/57.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/58.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/60.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/64.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/66.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/72.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/76.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/80.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/87.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/88.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/92.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/Contents.json +0 -0
|
@@ -5,25 +5,22 @@ require 'rubygems'
|
|
|
5
5
|
class BrandsManager
|
|
6
6
|
include Singleton
|
|
7
7
|
|
|
8
|
+
# Class method to access the singleton instance
|
|
9
|
+
def self.instance
|
|
10
|
+
@instance ||= new
|
|
11
|
+
end
|
|
12
|
+
|
|
8
13
|
def initialize
|
|
9
14
|
brands_list_path = FilePath.brands_list
|
|
10
15
|
@brands_list = JSON.parse(File.read(brands_list_path))
|
|
11
16
|
end
|
|
12
17
|
|
|
13
|
-
def first_brand
|
|
14
|
-
brands_list.first
|
|
15
|
-
end
|
|
16
|
-
|
|
17
18
|
def first_brand_key
|
|
18
19
|
brands_list.first["key"]
|
|
19
20
|
rescue
|
|
20
21
|
nil
|
|
21
22
|
end
|
|
22
23
|
|
|
23
|
-
def brand_name(brand_key)
|
|
24
|
-
brand_data(brand_key)["name"]
|
|
25
|
-
end
|
|
26
|
-
|
|
27
24
|
def brand_with_configurations(brand_key)
|
|
28
25
|
configurations = BrandConfigurationsManager.new(brand_key).create
|
|
29
26
|
{
|
|
@@ -41,17 +38,8 @@ class BrandsManager
|
|
|
41
38
|
@brands_list["brands"]
|
|
42
39
|
end
|
|
43
40
|
|
|
44
|
-
def find(brand_key)
|
|
45
|
-
brands = brands_list
|
|
46
|
-
brands.find { |b| b["key"] == brand_key }
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def brands_json
|
|
50
|
-
@brands_list
|
|
51
|
-
end
|
|
52
|
-
|
|
53
41
|
def exists(brand_key)
|
|
54
|
-
!brand_data(brand_key).nil?
|
|
42
|
+
!brand_data(brand_key).nil? && File.exist?(FilePath.brand(brand_key))
|
|
55
43
|
end
|
|
56
44
|
|
|
57
45
|
def add_brand(brand_name, brand_key)
|
|
@@ -59,11 +47,11 @@ class BrandsManager
|
|
|
59
47
|
existing_brand = brand_data(brand_key)
|
|
60
48
|
if existing_brand
|
|
61
49
|
update_brand(brands_list.index(existing_brand), brand)
|
|
62
|
-
Solara.logger.debug("#{brand_name} Brand updated in the list.")
|
|
50
|
+
Solara.logger.debug("#{brand_name} Brand updated in the brands list.")
|
|
63
51
|
else
|
|
64
52
|
brands_list.push(brand)
|
|
65
53
|
save_brands_list
|
|
66
|
-
Solara.logger.debug("#{brand_name} added to the list.")
|
|
54
|
+
Solara.logger.debug("#{brand_name} added to the brands list.")
|
|
67
55
|
end
|
|
68
56
|
end
|
|
69
57
|
|
|
@@ -71,13 +59,6 @@ class BrandsManager
|
|
|
71
59
|
JSON.parse(File.read(FilePath.current_brand))
|
|
72
60
|
end
|
|
73
61
|
|
|
74
|
-
def current_brand_content_changed(brand_key)
|
|
75
|
-
unless is_current_brand(brand_key)
|
|
76
|
-
return false
|
|
77
|
-
end
|
|
78
|
-
current_brand['content_changed'] == true
|
|
79
|
-
end
|
|
80
|
-
|
|
81
62
|
def set_current_brand_content_changed(brand_key, changed)
|
|
82
63
|
unless is_current_brand(brand_key)
|
|
83
64
|
return false
|
|
@@ -85,7 +66,7 @@ class BrandsManager
|
|
|
85
66
|
Solara.logger.debug("")
|
|
86
67
|
brand = current_brand
|
|
87
68
|
brand['content_changed'] = changed
|
|
88
|
-
|
|
69
|
+
save_current_brand_data(brand)
|
|
89
70
|
Solara.logger.debug("#{brand_key} changed saved to current_brand.json.")
|
|
90
71
|
end
|
|
91
72
|
|
|
@@ -95,17 +76,17 @@ class BrandsManager
|
|
|
95
76
|
|
|
96
77
|
def save_current_brand(brand_key)
|
|
97
78
|
brand = brand_data(brand_key)
|
|
98
|
-
|
|
79
|
+
save_current_brand_data(brand)
|
|
99
80
|
Solara.logger.debug("#{brand_key} saved as current brand.")
|
|
100
81
|
end
|
|
101
82
|
|
|
102
|
-
def
|
|
103
|
-
|
|
83
|
+
def save_current_brand_data(brand_data)
|
|
84
|
+
path = FilePath.current_brand
|
|
104
85
|
|
|
105
86
|
# Create the file if it doesn't exist
|
|
106
|
-
FileUtils.touch(
|
|
87
|
+
FileUtils.touch(path) unless File.exist?(path)
|
|
107
88
|
|
|
108
|
-
File.open(
|
|
89
|
+
File.open(path, 'w') do |file|
|
|
109
90
|
file.write(JSON.pretty_generate(brand_data))
|
|
110
91
|
end
|
|
111
92
|
|
|
@@ -128,7 +109,7 @@ class BrandsManager
|
|
|
128
109
|
if index
|
|
129
110
|
brand_dir = FilePath.brand(brand_key)
|
|
130
111
|
remove_brand(index)
|
|
131
|
-
|
|
112
|
+
FileManager.delete_if_exists(brand_dir)
|
|
132
113
|
save_brands_list
|
|
133
114
|
Solara.logger.debug("Brand removed.")
|
|
134
115
|
else
|
|
@@ -136,11 +117,6 @@ class BrandsManager
|
|
|
136
117
|
end
|
|
137
118
|
end
|
|
138
119
|
|
|
139
|
-
# Class method to access the singleton instance
|
|
140
|
-
def self.instance
|
|
141
|
-
@instance ||= new
|
|
142
|
-
end
|
|
143
|
-
|
|
144
120
|
private
|
|
145
121
|
|
|
146
122
|
def save_brands_list
|
|
@@ -3,6 +3,25 @@ import BrandDetailModel from './BrandDetailModel.js';
|
|
|
3
3
|
import BrandDetailView from './BrandDetailView.js';
|
|
4
4
|
import BrandDetailController from './BrandDetailController.js';
|
|
5
5
|
|
|
6
|
+
window.onload = function () {
|
|
7
|
+
document.getElementById('loadingOverlay').style.display = 'none';
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
let lastScrollTop = 0;
|
|
11
|
+
const header = document.getElementById('header');
|
|
12
|
+
|
|
13
|
+
window.addEventListener('scroll', function () {
|
|
14
|
+
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
15
|
+
if (scrollTop > lastScrollTop) {
|
|
16
|
+
// Scrolling down
|
|
17
|
+
header.classList.add('scroll-down');
|
|
18
|
+
} else {
|
|
19
|
+
// Scrolling up
|
|
20
|
+
header.classList.remove('scroll-down');
|
|
21
|
+
}
|
|
22
|
+
lastScrollTop = scrollTop;
|
|
23
|
+
});
|
|
24
|
+
|
|
6
25
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
7
26
|
const model = new BrandDetailModel();
|
|
8
27
|
const view = new BrandDetailView(model);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {DataSource} from './BrandDetailModel.js';
|
|
2
|
+
import InfoPlistStringCatalogManager from "./InfoPlistStringCatalogManager.js";
|
|
2
3
|
|
|
3
4
|
class BrandDetailController {
|
|
4
5
|
constructor(model, view) {
|
|
@@ -112,8 +113,11 @@ class BrandDetailController {
|
|
|
112
113
|
|
|
113
114
|
async onLoadSections(configuraationsResult) {
|
|
114
115
|
try {
|
|
116
|
+
this.view.addBrandOverlay.style.display = 'none'
|
|
117
|
+
this.view.header.style.display = 'flex';
|
|
115
118
|
this.view.updateAppNameTitle(`${configuraationsResult.brand.key} (${configuraationsResult.brand.name})`);
|
|
116
119
|
await this.showSections(configuraationsResult);
|
|
120
|
+
this.view.showIndex();
|
|
117
121
|
} catch (error) {
|
|
118
122
|
console.error('Error initializing app:', error);
|
|
119
123
|
alert(error.message);
|
|
@@ -142,10 +146,17 @@ class BrandDetailController {
|
|
|
142
146
|
const sectionInfo = sectionItems[i];
|
|
143
147
|
console.log('Processing section:', i, sectionInfo);
|
|
144
148
|
|
|
145
|
-
if (sectionInfo.key === 'theme') {
|
|
149
|
+
if (sectionInfo.key === 'theme.json') {
|
|
146
150
|
this.createThemeSections(sectionInfo)
|
|
151
|
+
} else if (sectionInfo.key === 'InfoPlist.xcstrings') {
|
|
152
|
+
this.createSection(
|
|
153
|
+
sectionInfo.key,
|
|
154
|
+
sectionInfo,
|
|
155
|
+
new InfoPlistStringCatalogManager(sectionInfo.content).extractLocalizations(),
|
|
156
|
+
sectionInfo.name,
|
|
157
|
+
sectionInfo.inputType)
|
|
147
158
|
} else {
|
|
148
|
-
this.createSection(sectionInfo, sectionInfo.content, sectionInfo.name, sectionInfo.inputType)
|
|
159
|
+
this.createSection(sectionInfo.key, sectionInfo, sectionInfo.content, sectionInfo.name, sectionInfo.inputType)
|
|
149
160
|
}
|
|
150
161
|
}
|
|
151
162
|
} catch (error) {
|
|
@@ -155,15 +166,42 @@ class BrandDetailController {
|
|
|
155
166
|
}
|
|
156
167
|
|
|
157
168
|
createThemeSections(sectionInfo) {
|
|
158
|
-
this.createSection(sectionInfo
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
this.createSection(`${sectionInfo.key}_colors`,
|
|
170
|
+
sectionInfo,
|
|
171
|
+
sectionInfo.content.colors,
|
|
172
|
+
'Theme Colors',
|
|
173
|
+
'color',
|
|
174
|
+
'colors')
|
|
175
|
+
this.createSection(`${sectionInfo.key}_typography`,
|
|
176
|
+
sectionInfo,
|
|
177
|
+
sectionInfo.content.typography,
|
|
178
|
+
'Theme Typography',
|
|
179
|
+
'text',
|
|
180
|
+
'typography')
|
|
181
|
+
this.createSection(`${sectionInfo.key}_spacing`,
|
|
182
|
+
sectionInfo,
|
|
183
|
+
sectionInfo.content.spacing,
|
|
184
|
+
'Theme Spacing', 'text',
|
|
185
|
+
'spacing')
|
|
186
|
+
this.createSection(
|
|
187
|
+
`${sectionInfo.key}_borderRadius`,
|
|
188
|
+
sectionInfo,
|
|
189
|
+
sectionInfo.content.borderRadius,
|
|
190
|
+
'Theme Border Radius',
|
|
191
|
+
'text',
|
|
192
|
+
'borderRadius')
|
|
193
|
+
this.createSection(
|
|
194
|
+
`${sectionInfo.key}_elevation`,
|
|
195
|
+
sectionInfo,
|
|
196
|
+
sectionInfo.content.elevation,
|
|
197
|
+
'Theme Elevation',
|
|
198
|
+
'text',
|
|
199
|
+
'elevation')
|
|
163
200
|
}
|
|
164
201
|
|
|
165
|
-
createSection(sectionInfo, content, sectionName, inputType, propertiesGroupName = null) {
|
|
202
|
+
createSection(id, sectionInfo, content, sectionName, inputType, propertiesGroupName = null) {
|
|
166
203
|
const sectionElement = this.view.createSection(sectionInfo.key, sectionName, inputType);
|
|
204
|
+
sectionElement.id = id;
|
|
167
205
|
sectionElement.dataset.propertiesGroupName = propertiesGroupName
|
|
168
206
|
|
|
169
207
|
this.view.sectionsContainer.appendChild(sectionElement);
|
|
@@ -208,6 +246,8 @@ class BrandDetailController {
|
|
|
208
246
|
if (input.classList.contains('array-input')) {
|
|
209
247
|
const arrayItemsContainer = input.closest('.input-wrapper').querySelector('.array-items-container');
|
|
210
248
|
current[lastKey] = this.getArrayValue(arrayItemsContainer);
|
|
249
|
+
} else if (input.type === 'checkbox') {
|
|
250
|
+
current[lastKey] = input.checked;
|
|
211
251
|
} else {
|
|
212
252
|
let value = input.value;
|
|
213
253
|
if (input.type === 'color') {
|
|
@@ -358,4 +398,6 @@ class BrandDetailController {
|
|
|
358
398
|
|
|
359
399
|
}
|
|
360
400
|
|
|
401
|
+
|
|
402
|
+
|
|
361
403
|
export default BrandDetailController;
|
|
@@ -14,9 +14,7 @@ class BrandDetailModel {
|
|
|
14
14
|
this.brandKey = this.getQueryFromUrl('brand_key');
|
|
15
15
|
|
|
16
16
|
const sourceFromUrl = this.getQueryFromUrl('source');
|
|
17
|
-
|
|
18
|
-
this.source = sourceFromUrl === DataSource.LOCAL ? DataSource.LOCAL : DataSource.REMOTE;
|
|
19
|
-
// this.source = DataSource.REMOTE;
|
|
17
|
+
this.source = sourceFromUrl === DataSource.LOCAL ? DataSource.LOCAL : DataSource.REMOTE;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
getQueryFromUrl(name) {
|
|
@@ -24,25 +22,11 @@ class BrandDetailModel {
|
|
|
24
22
|
}
|
|
25
23
|
|
|
26
24
|
async fetchBrandDetails() {
|
|
27
|
-
|
|
28
|
-
case DataSource.LOCAL:
|
|
29
|
-
return await this.localSource.fetchBrandDetails(this.brandKey);
|
|
30
|
-
case DataSource.REMOTE:
|
|
31
|
-
return await this.remoteSource.fetchBrandDetails(this.brandKey);
|
|
32
|
-
default:
|
|
33
|
-
throw new Error('Unknown data source');
|
|
34
|
-
}
|
|
25
|
+
return await this.localSource.fetchBrandDetails(this.brandKey);
|
|
35
26
|
}
|
|
36
27
|
|
|
37
28
|
async fetchCurrentBrand() {
|
|
38
|
-
|
|
39
|
-
case DataSource.LOCAL:
|
|
40
|
-
return await this.localSource.fetchCurrentBrand(this.brandKey);
|
|
41
|
-
case DataSource.REMOTE:
|
|
42
|
-
return await this.remoteSource.fetchCurrentBrand(this.brandKey);
|
|
43
|
-
default:
|
|
44
|
-
throw new Error('Unknown data source');
|
|
45
|
-
}
|
|
29
|
+
return await this.localSource.fetchCurrentBrand(this.brandKey);
|
|
46
30
|
}
|
|
47
31
|
|
|
48
32
|
async saveSection(sectionItem, configuration) {
|
|
@@ -50,29 +34,24 @@ class BrandDetailModel {
|
|
|
50
34
|
case DataSource.LOCAL:
|
|
51
35
|
return await this.localSource.saveSection(sectionItem, configuration, this.brandKey);
|
|
52
36
|
case DataSource.REMOTE:
|
|
53
|
-
|
|
37
|
+
// Saving is not supported remotely. Instead, user can export the brand.
|
|
38
|
+
return
|
|
54
39
|
default:
|
|
55
40
|
throw new Error('Unknown data source');
|
|
56
41
|
}
|
|
57
42
|
}
|
|
58
43
|
|
|
59
44
|
async switchToBrand() {
|
|
60
|
-
|
|
61
|
-
case DataSource.LOCAL:
|
|
62
|
-
return await this.localSource.switchToBrand(this.brandKey);
|
|
63
|
-
case DataSource.REMOTE:
|
|
64
|
-
return await this.remoteSource.switchToBrand(this.brandKey);
|
|
65
|
-
default:
|
|
66
|
-
throw new Error('Unknown data source');
|
|
67
|
-
}
|
|
45
|
+
return await this.localSource.switchToBrand(this.brandKey);
|
|
68
46
|
}
|
|
69
47
|
|
|
70
48
|
async checkBrandHealth() {
|
|
71
49
|
switch (this.source) {
|
|
72
50
|
case DataSource.LOCAL:
|
|
73
|
-
|
|
51
|
+
return await this.localSource.checkBrandHealth(this.brandKey);
|
|
74
52
|
case DataSource.REMOTE:
|
|
75
|
-
|
|
53
|
+
// Checking health is not supported remotely yet.
|
|
54
|
+
return
|
|
76
55
|
default:
|
|
77
56
|
throw new Error('Unknown data source');
|
|
78
57
|
}
|
|
@@ -7,7 +7,11 @@ import '../component/MessageBottomSheet.js';
|
|
|
7
7
|
class BrandDetailView {
|
|
8
8
|
constructor(model) {
|
|
9
9
|
this.model = model;
|
|
10
|
+
|
|
11
|
+
this.header = document.getElementById('header');
|
|
12
|
+
|
|
10
13
|
this.brandDetailsContainer = document.getElementById('brand-details-container');
|
|
14
|
+
this.addBrandOverlay = document.getElementById('add-brand-overlay');
|
|
11
15
|
this.addBrandContainer = document.getElementById('add-brand-container');
|
|
12
16
|
|
|
13
17
|
this.sectionsContainer = document.getElementById('sections');
|
|
@@ -38,11 +42,15 @@ class BrandDetailView {
|
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
async setupLocal() {
|
|
45
|
+
this.addBrandOverlay.style.display = 'none'
|
|
46
|
+
this.header.style.display = 'flex'
|
|
41
47
|
this.allBrandsButton.style.display = 'block'
|
|
42
48
|
this.toggleAddBrandContainer(false);
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
async setupRemote() {
|
|
52
|
+
this.addBrandOverlay.style.display = 'flex'
|
|
53
|
+
this.header.style.display = 'none'
|
|
46
54
|
this.allBrandsButton.style.display = 'none'
|
|
47
55
|
this.toggleAddBrandContainer(true);
|
|
48
56
|
}
|
|
@@ -76,7 +84,7 @@ class BrandDetailView {
|
|
|
76
84
|
|
|
77
85
|
const subtitleElement = document.createElement('p');
|
|
78
86
|
subtitleElement.className = 'section-subtitle';
|
|
79
|
-
subtitleElement.textContent =
|
|
87
|
+
subtitleElement.textContent = key;
|
|
80
88
|
titleContainer.appendChild(subtitleElement);
|
|
81
89
|
|
|
82
90
|
section.appendChild(titleContainer);
|
|
@@ -90,10 +98,12 @@ class BrandDetailView {
|
|
|
90
98
|
sectionElement.appendChild(this.createInputField(sectionItem, key, value, 'array'));
|
|
91
99
|
} else if (typeof value === 'object' && value !== null) {
|
|
92
100
|
for (const [subKey, subValue] of Object.entries(value)) {
|
|
93
|
-
|
|
101
|
+
const subInputType = subValue === true || subValue === false ? 'boolean' : inputType;
|
|
102
|
+
sectionElement.appendChild(this.createInputField(sectionItem, `${key}.${subKey}`, subValue, subInputType));
|
|
94
103
|
}
|
|
95
104
|
} else {
|
|
96
|
-
|
|
105
|
+
const fieldInputType = value === true || value === false ? 'boolean' : inputType;
|
|
106
|
+
sectionElement.appendChild(this.createInputField(sectionItem, key, value, fieldInputType));
|
|
97
107
|
}
|
|
98
108
|
}
|
|
99
109
|
}
|
|
@@ -142,11 +152,30 @@ class BrandDetailView {
|
|
|
142
152
|
input.value = '';
|
|
143
153
|
});
|
|
144
154
|
|
|
155
|
+
} else if (inputType === 'boolean') {
|
|
156
|
+
const checkbox = document.createElement('input');
|
|
157
|
+
checkbox.type = 'checkbox';
|
|
158
|
+
checkbox.id = key;
|
|
159
|
+
checkbox.checked = value;
|
|
160
|
+
|
|
161
|
+
const checkboxLabel = document.createElement('label');
|
|
162
|
+
checkboxLabel.className = 'checkbox-label';
|
|
163
|
+
checkboxLabel.htmlFor = key;
|
|
164
|
+
checkboxLabel.textContent = value ? 'True' : 'False';
|
|
165
|
+
|
|
166
|
+
checkbox.addEventListener('change', () => {
|
|
167
|
+
checkboxLabel.textContent = checkbox.checked ? 'True' : 'False';
|
|
168
|
+
this.onSectionChanged(sectionItem, container.closest('.section'));
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
inputWrapper.appendChild(checkbox);
|
|
172
|
+
inputWrapper.appendChild(checkboxLabel);
|
|
145
173
|
} else {
|
|
146
174
|
const input = document.createElement('input');
|
|
147
175
|
input.type = inputType;
|
|
148
176
|
input.id = key;
|
|
149
177
|
|
|
178
|
+
console.log(value)
|
|
150
179
|
if (inputType === 'color') {
|
|
151
180
|
input.value = value.startsWith('#') ? value : `#${value.substring(4)}`;
|
|
152
181
|
} else {
|
|
@@ -236,6 +265,23 @@ class BrandDetailView {
|
|
|
236
265
|
this.onboardSheet.show('Brand Details', 'Add Brand', onSubmit);
|
|
237
266
|
}
|
|
238
267
|
|
|
268
|
+
showIndex() {
|
|
269
|
+
const sectionsContainer = this.sectionsContainer;
|
|
270
|
+
const sectionElements = Array.from(sectionsContainer.querySelectorAll('.section'));
|
|
271
|
+
|
|
272
|
+
const indexElement = document.getElementById('index');
|
|
273
|
+
|
|
274
|
+
// Clear existing items if needed
|
|
275
|
+
indexElement.innerHTML = '';
|
|
276
|
+
|
|
277
|
+
sectionElements.forEach(sectionElement => {
|
|
278
|
+
const newItem = document.createElement('li');
|
|
279
|
+
newItem.classList.add('index-item');
|
|
280
|
+
newItem.innerHTML = `<a href="#${sectionElement.id}">${sectionElement.dataset.name}</a>`;
|
|
281
|
+
indexElement.appendChild(newItem);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
239
285
|
async hideOnboardBrandForm() {
|
|
240
286
|
this.onboardSheet.hide();
|
|
241
287
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class InfoPlistStringCatalogManager {
|
|
2
|
+
constructor(jsonData) {
|
|
3
|
+
this.data = jsonData;
|
|
4
|
+
this.localizations = {};
|
|
5
|
+
this.extractLocalizations();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
extractLocalizations() {
|
|
9
|
+
for (const [key, details] of Object.entries(this.data.strings)) {
|
|
10
|
+
for (const [lang, localization] of Object.entries(details.localizations)) {
|
|
11
|
+
const formattedKey = `${key}.${lang}`;
|
|
12
|
+
this.localizations[formattedKey] = localization.stringUnit.value;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return this.localizations
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default InfoPlistStringCatalogManager;
|