Skip to content

Commit

Permalink
Solara
Browse files Browse the repository at this point in the history
  • Loading branch information
IdeaS0ft committed Sep 9, 2024
1 parent 334856d commit 8c7797b
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 6 deletions.
25 changes: 25 additions & 0 deletions solara/lib/core/dashboard/brand/BrandController.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,31 @@ class BrandController {
}

async initRemote() {
this.view.uploadJsonBtn.addEventListener('click', async () => {
try {
const [fileHandle] = await window.showOpenFilePicker({
types: [{
description: 'JSON File',
accept: {
'application/json': ['.json'],
},
}],
});

const file = await fileHandle.getFile();

const json = await this.model.getBrandConfigurationsJsonFromDirectory(file);

if (!json) {
alert("The selected JSON file is not a valid configuration for Solara brands.");
return
}
await this.addBrand(json.brand.key, json.brand.name, json.configurations)
} catch (error) {
console.error('Error:', error);
}
});

this.view.uploadBrandBtn.addEventListener('click', async () => {
try {
const dirHandle = await window.showDirectoryPicker();
Expand Down
8 changes: 6 additions & 2 deletions solara/lib/core/dashboard/brand/BrandModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class BrandModel {

const sourceFromUrl = this.getQueryFromUrl('source');
// TODO: uncomment
this.source = sourceFromUrl === DataSource.LOCAL ? DataSource.LOCAL : DataSource.REMOTE;
// this.source = DataSource.REMOTE;
// this.source = sourceFromUrl === DataSource.LOCAL ? DataSource.LOCAL : DataSource.REMOTE;
this.source = DataSource.REMOTE;
}

getQueryFromUrl(name) {
Expand Down Expand Up @@ -85,6 +85,10 @@ class BrandModel {
async createBrandConfigurationsFromDirectory(dirHandle) {
return await this.remoteSource.createBrandConfigurationsFromDirectory(dirHandle);
}

async getBrandConfigurationsJsonFromDirectory(dirHandle) {
return await this.remoteSource.getBrandConfigurationsJsonFromDirectory(dirHandle);
}
}

export default BrandModel;
1 change: 1 addition & 0 deletions solara/lib/core/dashboard/brand/BrandView.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class BrandView {
this.messageBottomSheet = document.getElementById('messageBottomSheet');

this.uploadBrandBtn = document.getElementById('uploadBrandBtn');
this.uploadJsonBtn = document.getElementById('uploadJsonBtn');
this.addNewBrandBtn = document.getElementById('newBrandBtn');
this.downloadBrandBtn = document.getElementById('downloadBrand');
this.allBrandsButton = document.getElementById('allBrandsButton');
Expand Down
52 changes: 48 additions & 4 deletions solara/lib/core/dashboard/brand/brand.html
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,6 @@
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
z-index: 1000;
animation: fadeIn 0.5s ease-out;
display: none;
}

@keyframes fadeIn {
Expand All @@ -366,13 +365,20 @@
.add-brand-container img {
width: 150px;
height: 150px;
margin-bottom: 20px;
}

.add-brand-container h2 {
font-size: 18px;
color: #333;
margin-bottom: 30px;
animation: slideDown 0.5s ease-out 0.3s both;
}

.add-brand-container button {
display: block;
width: 200px;
margin: 10px auto;
margin: 20px auto;
padding: 15px;
font-size: 18px;
background-color: var(--primary-color);
Expand All @@ -381,13 +387,46 @@
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease;
opacity: 0;
animation: fadeInButton 0.5s ease-out forwards;
}

.add-brand-container button:hover {
background-color: #3A7BC8;
transform: scale(1.05);
}

.button-message {
font-size: 18px;
color: #666;
margin-bottom: 5px;
opacity: 0;
animation: fadeInMessage 0.5s ease-out forwards;
}

@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

@keyframes fadeInButton {
to {
opacity: 1;
}
}

@keyframes fadeInMessage {
to {
opacity: 1;
}
}


/* Hide the brand-details-container by default */
#brand-details-container {
Expand All @@ -407,8 +446,13 @@ <h1><span id="brandNametitle"></span></h1>

<div id="add-brand-container" class="add-brand-container">
<img src="../solara.png" alt="Solara Logo">
<button id="uploadBrandBtn">Upload Brand</button>
<button id="newBrandBtn">New Brand</button>
<h2>Solara simplifies the management of your brand configurations, allowing you to access and update them anytime, anywhere.</h2>
<div class="button-message">You can select a JSON file containing brand configurations that were exported using Solara.</div>
<button id="uploadJsonBtn" style=" animation-delay: 0.5s;">Upload JSON</button>
<div class="button-message" style=" animation-delay: 0.7s;">Alternatively, upload from a directory that contains the brand's JSON files.</div>
<button id="uploadBrandBtn" style=" animation-delay: 0.9s;">Upload Brand</button>
<div class="button-message" style=" animation-delay: 1.1s;">You also have the option to create new brand configurations.</div>
<button id="newBrandBtn" style=" animation-delay: 1.3s;">New Brand</button>
</div>

<onboard-bottom-sheet id="onboardBottomSheet"></onboard-bottom-sheet>
Expand Down
70 changes: 70 additions & 0 deletions solara/lib/core/dashboard/brand/source/BrandRemoteSource.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Ajv from 'https://cdn.skypack.dev/[email protected]';

class BrandRemoteSource {
constructor() {
}
Expand Down Expand Up @@ -133,6 +135,74 @@ class BrandRemoteSource {
return JSON.parse(configurations_template);
}

async getBrandConfigurationsJsonFromDirectory(dirHandle) {
const schema = {
"title": "Brand Configurations Schema",
"type": "object",
"properties": {
"brand": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": ["key", "name"]
},
"configurations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
},
"inputType": {
"type": "string",
"enum": ["color", "text"]
},
"content": {
"type": "object",
"additionalProperties": {}
}
},
"required": ["key", "name", "inputType", "content"]
}
}
},
"required": ["brand", "configurations"]
};

const ajv = new Ajv();
const validate = ajv.compile(schema);

const text = await dirHandle.text();
let json;

try {
json = JSON.parse(text);
} catch (e) {
console.error("Invalid JSON:", e);
return null
}

const valid = validate(json);

if (valid) {
return json;
} else {
console.error("Schema validation failed:", validate.errors);
}

return null;
}

async createBrandConfigurationsFromDirectory(dirHandle) {
const configList = [];
const expectedFiles = [
Expand Down

0 comments on commit 8c7797b

Please sign in to comment.