mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
Seed patchdb UI data (#1835)
* adjust types for patchdb ui data and create seed file * feat: For init and the migration use defaults * fix update path * update build for ui seed file * fix accidential revert * chore: Convert to do during the init * chore: Update the commit message Co-authored-by: BluJ <mogulslayer@gmail.com>
This commit is contained in:
8
Makefile
8
Makefile
@@ -8,7 +8,7 @@ COMPAT_SRC := $(shell find system-images/compat/ -not -path 'system-images/compa
|
|||||||
UTILS_SRC := $(shell find system-images/utils/ -not -name utils.tar)
|
UTILS_SRC := $(shell find system-images/utils/ -not -name utils.tar)
|
||||||
BINFMT_SRC := $(shell find system-images/binfmt/ -not -name binfmt.tar)
|
BINFMT_SRC := $(shell find system-images/binfmt/ -not -name binfmt.tar)
|
||||||
BACKEND_SRC := $(shell find backend/src) $(shell find backend/migrations) $(shell find patch-db/*/src) backend/Cargo.toml backend/Cargo.lock
|
BACKEND_SRC := $(shell find backend/src) $(shell find backend/migrations) $(shell find patch-db/*/src) backend/Cargo.toml backend/Cargo.lock
|
||||||
FRONTEND_SHARED_SRC := $(shell find frontend/projects/shared) $(shell find frontend/assets) $(shell ls -p frontend/ | grep -v / | sed 's/^/frontend\//g') frontend/node_modules frontend/config.json patch-db/client/dist
|
FRONTEND_SHARED_SRC := $(shell find frontend/projects/shared) $(shell find frontend/assets) $(shell ls -p frontend/ | grep -v / | sed 's/^/frontend\//g') frontend/node_modules frontend/config.json patch-db/client/dist frontend/patchdb-ui-seed.json
|
||||||
FRONTEND_UI_SRC := $(shell find frontend/projects/ui)
|
FRONTEND_UI_SRC := $(shell find frontend/projects/ui)
|
||||||
FRONTEND_SETUP_WIZARD_SRC := $(shell find frontend/projects/setup-wizard)
|
FRONTEND_SETUP_WIZARD_SRC := $(shell find frontend/projects/setup-wizard)
|
||||||
FRONTEND_DIAGNOSTIC_UI_SRC := $(shell find frontend/projects/diagnostic-ui)
|
FRONTEND_DIAGNOSTIC_UI_SRC := $(shell find frontend/projects/diagnostic-ui)
|
||||||
@@ -74,7 +74,7 @@ snapshots: libs/snapshot-creator/Cargo.toml
|
|||||||
cd libs/ && ./build-v8-snapshot.sh
|
cd libs/ && ./build-v8-snapshot.sh
|
||||||
cd libs/ && ./build-arm-v8-snapshot.sh
|
cd libs/ && ./build-arm-v8-snapshot.sh
|
||||||
|
|
||||||
$(EMBASSY_BINS): $(BACKEND_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE)
|
$(EMBASSY_BINS): $(BACKEND_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) frontend/patchdb-ui-seed.json
|
||||||
cd backend && ./build-prod.sh
|
cd backend && ./build-prod.sh
|
||||||
touch $(EMBASSY_BINS)
|
touch $(EMBASSY_BINS)
|
||||||
|
|
||||||
@@ -94,6 +94,10 @@ frontend/config.json: $(GIT_HASH_FILE) frontend/config-sample.json
|
|||||||
jq '.useMocks = false' frontend/config-sample.json > frontend/config.json
|
jq '.useMocks = false' frontend/config-sample.json > frontend/config.json
|
||||||
npm --prefix frontend run-script build-config
|
npm --prefix frontend run-script build-config
|
||||||
|
|
||||||
|
frontend/patchdb-ui-seed.json: frontend/package.json
|
||||||
|
jq '."ack-welcome" = "$(shell yq '.version' frontend/package.json)"' frontend/patchdb-ui-seed.json > ui-seed.tmp
|
||||||
|
mv ui-seed.tmp frontend/patchdb-ui-seed.json
|
||||||
|
|
||||||
patch-db/client/node_modules: patch-db/client/package.json
|
patch-db/client/node_modules: patch-db/client/package.json
|
||||||
npm --prefix patch-db/client ci
|
npm --prefix patch-db/client ci
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,44 @@ impl serde::ser::Serialize for CharSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait MergeWith {
|
||||||
|
fn merge_with(&mut self, other: &serde_json::Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MergeWith for serde_json::Value {
|
||||||
|
fn merge_with(&mut self, other: &serde_json::Value) {
|
||||||
|
use serde_json::Value::Object;
|
||||||
|
if let (Object(orig), Object(ref other)) = (self, other) {
|
||||||
|
for (key, val) in other.into_iter() {
|
||||||
|
match (orig.get_mut(key), val) {
|
||||||
|
(Some(new_orig @ Object(_)), other @ Object(_)) => {
|
||||||
|
new_orig.merge_with(other);
|
||||||
|
}
|
||||||
|
(None, _) => {
|
||||||
|
orig.insert(key.clone(), val.clone());
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn merge_with_tests() {
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
let mut a = json!(
|
||||||
|
{"a": 1, "c": {"d": "123"}, "i": [1,2,3], "j": {}, "k":[1,2,3], "l": "test"}
|
||||||
|
);
|
||||||
|
a.merge_with(
|
||||||
|
&json!({"a":"a", "b": "b", "c":{"d":"d", "e":"e"}, "f":{"g":"g"}, "h": [1,2,3], "i":"i", "j":[1,2,3], "k":{}}),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
a,
|
||||||
|
json!({"a": 1, "c": {"d": "123", "e":"e"}, "b":"b", "f": {"g":"g"}, "h":[1,2,3], "i":[1,2,3], "j": {}, "k":[1,2,3], "l": "test"})
|
||||||
|
)
|
||||||
|
}
|
||||||
pub mod serde_regex {
|
pub mod serde_regex {
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::*;
|
use serde::*;
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ impl Database {
|
|||||||
},
|
},
|
||||||
package_data: AllPackageData::default(),
|
package_data: AllPackageData::default(),
|
||||||
recovered_packages: BTreeMap::new(),
|
recovered_packages: BTreeMap::new(),
|
||||||
ui: Value::Object(Default::default()),
|
ui: serde_json::from_str(include_str!("../../../frontend/patchdb-ui-seed.json"))
|
||||||
|
.unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use helpers::NonDetachingJoinHandle;
|
|||||||
use patch_db::{DbHandle, LockReceipt, LockType};
|
use patch_db::{DbHandle, LockReceipt, LockType};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
|
use crate::config::util::MergeWith;
|
||||||
use crate::context::rpc::RpcContextConfig;
|
use crate::context::rpc::RpcContextConfig;
|
||||||
use crate::db::model::ServerStatus;
|
use crate::db::model::ServerStatus;
|
||||||
use crate::install::PKG_DOCKER_DIR;
|
use crate::install::PKG_DOCKER_DIR;
|
||||||
@@ -192,6 +193,25 @@ pub async fn init(cfg: &RpcContextConfig) -> Result<InitResult, Error> {
|
|||||||
.server_info()
|
.server_info()
|
||||||
.lock(&mut handle, LockType::Write)
|
.lock(&mut handle, LockType::Write)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let defaults: serde_json::Value =
|
||||||
|
serde_json::from_str(include_str!("../../frontend/patchdb-ui-seed.json")).map_err(|x| {
|
||||||
|
Error::new(
|
||||||
|
eyre!("Deserialization error {:?}", x),
|
||||||
|
crate::ErrorKind::Deserialization,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let mut ui = crate::db::DatabaseModel::new()
|
||||||
|
.ui()
|
||||||
|
.get(&mut handle, false)
|
||||||
|
.await?
|
||||||
|
.clone();
|
||||||
|
ui.merge_with(&defaults);
|
||||||
|
crate::db::DatabaseModel::new()
|
||||||
|
.ui()
|
||||||
|
.put(&mut handle, &ui)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let receipts = InitReceipts::new(&mut handle).await?;
|
let receipts = InitReceipts::new(&mut handle).await?;
|
||||||
|
|
||||||
let should_rebuild = tokio::fs::metadata(SYSTEM_REBUILD_PATH).await.is_ok()
|
let should_rebuild = tokio::fs::metadata(SYSTEM_REBUILD_PATH).await.is_ok()
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use emver::VersionRange;
|
use emver::VersionRange;
|
||||||
|
|
||||||
|
use crate::config::util::MergeWith;
|
||||||
use crate::hostname::{generate_id, get_hostname, sync_hostname};
|
use crate::hostname::{generate_id, get_hostname, sync_hostname};
|
||||||
|
use crate::ErrorKind;
|
||||||
|
|
||||||
use super::v0_3_0::V0_3_0_COMPAT;
|
use super::v0_3_0::V0_3_0_COMPAT;
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -35,28 +37,9 @@ impl VersionT for Version {
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
sync_hostname(db).await?;
|
sync_hostname(db).await?;
|
||||||
let mut ui = crate::db::DatabaseModel::new()
|
|
||||||
.ui()
|
|
||||||
.get(db, false)
|
|
||||||
.await?
|
|
||||||
.clone();
|
|
||||||
if let serde_json::Value::Object(ref mut ui) = ui {
|
|
||||||
ui.insert("ack-instructions".to_string(), serde_json::json!({}));
|
|
||||||
}
|
|
||||||
crate::db::DatabaseModel::new().ui().put(db, &ui).await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
async fn down<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
|
async fn down<Db: DbHandle>(&self, _db: &mut Db) -> Result<(), Error> {
|
||||||
let mut ui = crate::db::DatabaseModel::new()
|
|
||||||
.ui()
|
|
||||||
.get(db, false)
|
|
||||||
.await?
|
|
||||||
.clone();
|
|
||||||
if let serde_json::Value::Object(ref mut ui) = ui {
|
|
||||||
ui.remove("ack-instructions");
|
|
||||||
}
|
|
||||||
crate::db::DatabaseModel::new().ui().put(db, &ui).await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
frontend/patchdb-ui-seed.json
Normal file
17
frontend/patchdb-ui-seed.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": null,
|
||||||
|
"auto-check-updates": true,
|
||||||
|
"pkg-order": [],
|
||||||
|
"ack-welcome": "0.3.0",
|
||||||
|
"marketplace": {
|
||||||
|
"selected-id": null,
|
||||||
|
"known-hosts": {}
|
||||||
|
},
|
||||||
|
"dev": {},
|
||||||
|
"gaming": {
|
||||||
|
"snake": {
|
||||||
|
"high-score": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ack-instructions": {}
|
||||||
|
}
|
||||||
@@ -39,8 +39,8 @@ export class SnekDirective {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await this.embassyApi.setDbValue({
|
await this.embassyApi.setDbValue({
|
||||||
pointer: '/gaming',
|
pointer: '/gaming/snake/high-score',
|
||||||
value: { snake: { 'high-score': data.highScore } },
|
value: data.highScore,
|
||||||
})
|
})
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this.errToast.present(e)
|
this.errToast.present(e)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export class DeveloperListPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async openCreateProjectModal() {
|
async openCreateProjectModal() {
|
||||||
const projNumber = Object.keys(this.devData || {}).length + 1
|
const projNumber = Object.keys(this.devData).length + 1
|
||||||
const options: GenericInputOptions = {
|
const options: GenericInputOptions = {
|
||||||
title: 'Add new project',
|
title: 'Add new project',
|
||||||
message: 'Create a new dev project.',
|
message: 'Create a new dev project.',
|
||||||
@@ -130,7 +130,7 @@ export class DeveloperListPage {
|
|||||||
async createProject(name: string) {
|
async createProject(name: string) {
|
||||||
// fail silently if duplicate project name
|
// fail silently if duplicate project name
|
||||||
if (
|
if (
|
||||||
Object.values(this.devData || {})
|
Object.values(this.devData)
|
||||||
.map(v => v.name)
|
.map(v => v.name)
|
||||||
.includes(name)
|
.includes(name)
|
||||||
)
|
)
|
||||||
@@ -148,11 +148,7 @@ export class DeveloperListPage {
|
|||||||
.replace(/warning:/g, '# Optional\n warning:')
|
.replace(/warning:/g, '# Optional\n warning:')
|
||||||
|
|
||||||
const def = { name, config, instructions: SAMPLE_INSTUCTIONS }
|
const def = { name, config, instructions: SAMPLE_INSTUCTIONS }
|
||||||
if (this.devData) {
|
await this.api.setDbValue({ pointer: `/dev/${id}`, value: def })
|
||||||
await this.api.setDbValue({ pointer: `/dev/${id}`, value: def })
|
|
||||||
} else {
|
|
||||||
await this.api.setDbValue({ pointer: `/dev`, value: { [id]: def } })
|
|
||||||
}
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this.errToast.present(e)
|
this.errToast.present(e)
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export class MarketplacesPage {
|
|||||||
this.patch
|
this.patch
|
||||||
.watch$('ui', 'marketplace')
|
.watch$('ui', 'marketplace')
|
||||||
.pipe(distinctUntilChanged(), takeUntil(this.destroy$))
|
.pipe(distinctUntilChanged(), takeUntil(this.destroy$))
|
||||||
.subscribe((mp: UIMarketplaceData | undefined) => {
|
.subscribe((mp: UIMarketplaceData) => {
|
||||||
let marketplaces: Marketplaces = [
|
let marketplaces: Marketplaces = [
|
||||||
{
|
{
|
||||||
id: null,
|
id: null,
|
||||||
@@ -74,17 +74,15 @@ export class MarketplacesPage {
|
|||||||
url: this.config.marketplace.url,
|
url: this.config.marketplace.url,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
if (mp) {
|
this.selectedId = mp['selected-id']
|
||||||
this.selectedId = mp['selected-id']
|
const alts = Object.entries(mp['known-hosts']).map(([k, v]) => {
|
||||||
const alts = Object.entries(mp['known-hosts']).map(([k, v]) => {
|
return {
|
||||||
return {
|
id: k,
|
||||||
id: k,
|
name: v.name,
|
||||||
name: v.name,
|
url: v.url,
|
||||||
url: v.url,
|
}
|
||||||
}
|
})
|
||||||
})
|
marketplaces = marketplaces.concat(alts)
|
||||||
marketplaces = marketplaces.concat(alts)
|
|
||||||
}
|
|
||||||
this.marketplaces = marketplaces
|
this.marketplaces = marketplaces
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ export const mockPatchData: DataModel = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
dev: {},
|
||||||
|
gaming: {
|
||||||
|
snake: {
|
||||||
|
'high-score': 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
'ack-instructions': {},
|
'ack-instructions': {},
|
||||||
},
|
},
|
||||||
'server-info': {
|
'server-info': {
|
||||||
|
|||||||
@@ -37,13 +37,6 @@ export class MarketplaceService extends AbstractMarketplaceService {
|
|||||||
private readonly uiMarketplaceData$ = this.patch
|
private readonly uiMarketplaceData$ = this.patch
|
||||||
.watch$('ui', 'marketplace')
|
.watch$('ui', 'marketplace')
|
||||||
.pipe(
|
.pipe(
|
||||||
map(
|
|
||||||
m =>
|
|
||||||
m || {
|
|
||||||
'selected-id': null,
|
|
||||||
'known-hosts': {},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
distinctUntilChanged(
|
distinctUntilChanged(
|
||||||
(prev, curr) => prev['selected-id'] === curr['selected-id'],
|
(prev, curr) => prev['selected-id'] === curr['selected-id'],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ export interface DataModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface UIData {
|
export interface UIData {
|
||||||
name: string
|
name: string | null
|
||||||
'auto-check-updates': boolean
|
'auto-check-updates': boolean
|
||||||
'pkg-order': string[]
|
'pkg-order': string[]
|
||||||
'ack-welcome': string // EOS version
|
'ack-welcome': string // EOS emver
|
||||||
marketplace?: UIMarketplaceData
|
marketplace: UIMarketplaceData
|
||||||
dev?: DevData
|
dev: DevData
|
||||||
gaming?: {
|
gaming: {
|
||||||
snake: {
|
snake: {
|
||||||
'high-score': number
|
'high-score': number
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,5 @@ import { firstValueFrom, map } from 'rxjs'
|
|||||||
export function getMarketplace(
|
export function getMarketplace(
|
||||||
patch: PatchDB<DataModel>,
|
patch: PatchDB<DataModel>,
|
||||||
): Promise<UIMarketplaceData> {
|
): Promise<UIMarketplaceData> {
|
||||||
return firstValueFrom(
|
return firstValueFrom(patch.watch$('ui', 'marketplace'))
|
||||||
patch.watch$('ui', 'marketplace').pipe(
|
|
||||||
map(
|
|
||||||
m =>
|
|
||||||
m || {
|
|
||||||
'selected-id': null,
|
|
||||||
'known-hosts': {},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user