diff --git a/core/startos/bindings/PackageDataEntry.ts b/core/startos/bindings/PackageDataEntry.ts
index 8b906bb90..5729e6bc3 100644
--- a/core/startos/bindings/PackageDataEntry.ts
+++ b/core/startos/bindings/PackageDataEntry.ts
@@ -16,6 +16,7 @@ export type PackageDataEntry = {
developerKey: string;
icon: DataUrl;
lastBackup: string | null;
+ nextBackup: string | null;
currentDependencies: CurrentDependencies;
actions: { [key: ActionId]: ActionMetadata };
serviceInterfaces: {
diff --git a/web/package-lock.json b/web/package-lock.json
index 36c57fedc..a5ab3874a 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -23,17 +23,17 @@
"@start9labs/argon2": "^0.1.0",
"@start9labs/emver": "^0.1.5",
"@start9labs/start-sdk": "file:../sdk/dist",
- "@taiga-ui/addon-charts": "3.73.0",
- "@taiga-ui/addon-commerce": "3.73.0",
- "@taiga-ui/addon-mobile": "3.73.0",
- "@taiga-ui/cdk": "3.73.0",
- "@taiga-ui/core": "3.73.0",
- "@taiga-ui/experimental": "3.73.0",
- "@taiga-ui/icons": "3.73.0",
- "@taiga-ui/kit": "3.73.0",
- "@taiga-ui/styles": "3.73.0",
+ "@taiga-ui/addon-charts": "3.77.1",
+ "@taiga-ui/addon-commerce": "3.77.1",
+ "@taiga-ui/addon-mobile": "3.77.1",
+ "@taiga-ui/cdk": "3.77.1",
+ "@taiga-ui/core": "3.77.1",
+ "@taiga-ui/experimental": "3.77.1",
+ "@taiga-ui/icons": "3.77.1",
+ "@taiga-ui/kit": "3.77.1",
+ "@taiga-ui/styles": "3.77.1",
"@tinkoff/ng-dompurify": "4.0.0",
- "@tinkoff/ng-event-plugins": "3.1.1",
+ "@tinkoff/ng-event-plugins": "3.2.0",
"ansi-to-html": "^0.7.2",
"base64-js": "^1.5.1",
"cbor": "npm:@jprochazk/cbor@^0.4.9",
@@ -5085,72 +5085,72 @@
"link": true
},
"node_modules/@taiga-ui/addon-charts": {
- "version": "3.73.0",
- "resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-3.73.0.tgz",
- "integrity": "sha512-4zK0sXqMtuz2fVlsgbnBLMuzphCqLbsSR/owMzJxAsrlZV7Lv1VUaMHHe9sdhDBmvO3VZu2d1wNuv/Z1jVfpYQ==",
+ "version": "3.77.1",
+ "resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-3.77.1.tgz",
+ "integrity": "sha512-yk9cvMewoRRVxTv1sIorVgO9GBkleQyRzkT774RPQACQHizGS2Sq5dQMtetwD3usPmLR2GblDR6NM+iOyHhMIA==",
"dependencies": {
- "tslib": "2.6.2"
+ "tslib": "^2.6.2"
},
"peerDependencies": {
"@angular/common": ">=12.0.0",
"@angular/core": ">=12.0.0",
- "@ng-web-apis/common": "3.0.6",
- "@taiga-ui/cdk": "^3.73.0",
- "@taiga-ui/core": "^3.73.0",
- "@tinkoff/ng-polymorpheus": "4.3.0"
+ "@ng-web-apis/common": "^3.0.6",
+ "@taiga-ui/cdk": "^3.77.1",
+ "@taiga-ui/core": "^3.77.1",
+ "@tinkoff/ng-polymorpheus": "^4.3.0"
}
},
"node_modules/@taiga-ui/addon-commerce": {
- "version": "3.73.0",
- "resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-3.73.0.tgz",
- "integrity": "sha512-LVK1ROrutavqIvOEHCaXRcX9ZNyznz3cCQFhbLldTIgTSXoYQNNitAgG4cRmntLioLupcVnKt0JZOHiObEx49A==",
+ "version": "3.77.1",
+ "resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-3.77.1.tgz",
+ "integrity": "sha512-4qNgDZfxyzTHQdKaerw28xP8d2PCuumLM9xjlRbNE5XcnhUI+rccgZOV9MtZtQoNBl++OBPmbaT2/9+zbSqbxg==",
"dependencies": {
- "tslib": "2.6.2"
+ "tslib": "^2.6.2"
},
"peerDependencies": {
"@angular/common": ">=12.0.0",
"@angular/core": ">=12.0.0",
"@angular/forms": ">=12.0.0",
- "@maskito/angular": "1.9.0",
- "@maskito/core": "1.9.0",
- "@maskito/kit": "1.9.0",
- "@ng-web-apis/common": "3.0.6",
- "@taiga-ui/cdk": "^3.73.0",
- "@taiga-ui/core": "^3.73.0",
- "@taiga-ui/i18n": "^3.73.0",
- "@taiga-ui/kit": "^3.73.0",
- "@tinkoff/ng-polymorpheus": "4.3.0",
+ "@maskito/angular": "^1.9.0",
+ "@maskito/core": "^1.9.0",
+ "@maskito/kit": "^1.9.0",
+ "@ng-web-apis/common": "^3.0.6",
+ "@taiga-ui/cdk": "^3.77.1",
+ "@taiga-ui/core": "^3.77.1",
+ "@taiga-ui/i18n": "^3.77.1",
+ "@taiga-ui/kit": "^3.77.1",
+ "@tinkoff/ng-polymorpheus": "^4.3.0",
"rxjs": ">=6.0.0"
}
},
"node_modules/@taiga-ui/addon-mobile": {
- "version": "3.73.0",
- "resolved": "https://registry.npmjs.org/@taiga-ui/addon-mobile/-/addon-mobile-3.73.0.tgz",
- "integrity": "sha512-XJ8xlmnp3fU02KjqgFtUCkcMsPmdIvksI/vmK7ZCaNunsGIYVAGSqw3/yyRV+HkX1ccqynX5johv+lligD9RtA==",
+ "version": "3.77.1",
+ "resolved": "https://registry.npmjs.org/@taiga-ui/addon-mobile/-/addon-mobile-3.77.1.tgz",
+ "integrity": "sha512-kRa9uNdnY9Tyz8FdGXqgbL7cKZ1Z43K3Kjey9tX3uf4BEkODPNVuQFTNzuZvOt6/ql+XtPxi/hU19ii5rvKz3A==",
"dependencies": {
- "tslib": "2.6.2"
+ "tslib": "^2.6.2"
},
"peerDependencies": {
"@angular/cdk": ">=12.0.0",
"@angular/common": ">=12.0.0",
"@angular/core": ">=12.0.0",
- "@ng-web-apis/common": "3.0.6",
- "@taiga-ui/cdk": "^3.73.0",
- "@taiga-ui/core": "^3.73.0",
- "@taiga-ui/kit": "^3.73.0",
- "@tinkoff/ng-polymorpheus": "4.3.0",
+ "@ng-web-apis/common": "^3.0.6",
+ "@taiga-ui/cdk": "^3.77.1",
+ "@taiga-ui/core": "^3.77.1",
+ "@taiga-ui/kit": "^3.77.1",
+ "@tinkoff/ng-polymorpheus": "^4.3.0",
"rxjs": ">=6.0.0"
}
},
"node_modules/@taiga-ui/cdk": {
- "version": "3.73.0",
- "resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-3.73.0.tgz",
- "integrity": "sha512-bxgbetJcbB+9h6ZO0ht076A9K0UOemr5D339o8h2tQpFnjOiw7gQ0ZnpNrKXXOpb5eASnptulmwtITvagpE1lg==",
+ "version": "3.77.1",
+ "resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-3.77.1.tgz",
+ "integrity": "sha512-mqT1Rz/JWqah4aNVRD3iEND4XdkfsOxV100D0gbdFD5/aaiMTyL6oMEP2GGE0lSsuk1mRCixkDW0qPCbhG21yQ==",
"dependencies": {
"@ng-web-apis/common": "3.0.6",
"@ng-web-apis/mutation-observer": "3.1.0",
"@ng-web-apis/resize-observer": "3.0.6",
- "@tinkoff/ng-event-plugins": "3.1.1",
+ "@tinkoff/ng-event-plugins": "3.2.0",
"@tinkoff/ng-polymorpheus": "4.3.0",
"tslib": "2.6.2"
},
@@ -5172,12 +5172,12 @@
"optional": true
},
"node_modules/@taiga-ui/core": {
- "version": "3.73.0",
- "resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-3.73.0.tgz",
- "integrity": "sha512-zQ+qhgBxQK6+SrzfSHIotKI00xbPu0ZTBFyYGUT8zD0If4aN5oeR+Q5A9kUb/0rEPsHcg04TcAEtAsAtG2l/oA==",
+ "version": "3.77.1",
+ "resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-3.77.1.tgz",
+ "integrity": "sha512-RjrOZtkQbb+Hw+7wMTt8j76OkGiLrCDb2Ol1rmngFQfzPX5OlaRkBtNhCNoyBtI9rl4CCX2/ViCGnGmrIkHu6g==",
"dependencies": {
- "@taiga-ui/i18n": "^3.73.0",
- "tslib": "2.6.2"
+ "@taiga-ui/i18n": "^3.77.1",
+ "tslib": "^2.6.2"
},
"peerDependencies": {
"@angular/animations": ">=12.0.0",
@@ -5186,68 +5186,68 @@
"@angular/forms": ">=12.0.0",
"@angular/platform-browser": ">=12.0.0",
"@angular/router": ">=12.0.0",
- "@ng-web-apis/common": "3.0.6",
- "@ng-web-apis/mutation-observer": "3.1.0",
- "@taiga-ui/cdk": "^3.73.0",
- "@taiga-ui/i18n": "^3.73.0",
- "@tinkoff/ng-event-plugins": "3.1.1",
- "@tinkoff/ng-polymorpheus": "4.3.0",
+ "@ng-web-apis/common": "^3.0.6",
+ "@ng-web-apis/mutation-observer": "^3.1.0",
+ "@taiga-ui/cdk": "^3.77.1",
+ "@taiga-ui/i18n": "^3.77.1",
+ "@tinkoff/ng-event-plugins": "^3.2.0",
+ "@tinkoff/ng-polymorpheus": "^4.3.0",
"rxjs": ">=6.0.0"
}
},
"node_modules/@taiga-ui/experimental": {
- "version": "3.73.0",
- "resolved": "https://registry.npmjs.org/@taiga-ui/experimental/-/experimental-3.73.0.tgz",
- "integrity": "sha512-FlMrasE7emFTNCN2a6xdU9ZCH7HIAU/xd+jjqxsi9Cf37juDLFtInFjFyQ9ZuEnhIJP3POTX+d8t/niRTPwpNw==",
+ "version": "3.77.1",
+ "resolved": "https://registry.npmjs.org/@taiga-ui/experimental/-/experimental-3.77.1.tgz",
+ "integrity": "sha512-UVmP0y1w9VvOoQoTH4VByZ3m45OcC0Lw//rsrNMicPCX9b5IJxgEjUAmJ+PZ/ecsgnDVKO0HD18cZt5uCVdy7w==",
"dependencies": {
- "tslib": "2.6.2"
+ "tslib": "^2.6.2"
},
"peerDependencies": {
"@angular/common": ">=12.0.0",
"@angular/core": ">=12.0.0",
- "@taiga-ui/addon-commerce": "^3.73.0",
- "@taiga-ui/cdk": "^3.73.0",
- "@taiga-ui/core": "^3.73.0",
- "@taiga-ui/kit": "^3.73.0",
- "@tinkoff/ng-polymorpheus": "4.3.0",
+ "@taiga-ui/addon-commerce": "^3.77.1",
+ "@taiga-ui/cdk": "^3.77.1",
+ "@taiga-ui/core": "^3.77.1",
+ "@taiga-ui/kit": "^3.77.1",
+ "@tinkoff/ng-polymorpheus": "^4.3.0",
"rxjs": ">=6.0.0"
}
},
"node_modules/@taiga-ui/i18n": {
- "version": "3.73.0",
- "resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.73.0.tgz",
- "integrity": "sha512-CLyYmnnL08+P5XvnKSMhZPpJyBs4199ApMX33hPBa4MvpmykUoVXQ0nXslLECSqAcfL39N9tzWKnxyLAavXjNw==",
+ "version": "3.77.1",
+ "resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.77.1.tgz",
+ "integrity": "sha512-rC2RYMFyaRHKcoU5WUKMe2DU0urRNh0daKvRIhp8t5AnTQE1MDZHRJYVCpysr8sfXvtJdr5oHoZccavzvqjqOQ==",
"dependencies": {
- "tslib": "2.6.2"
+ "tslib": "^2.6.2"
},
"peerDependencies": {
"@angular/core": ">=12.0.0",
- "@ng-web-apis/common": "3.0.6",
+ "@ng-web-apis/common": "^3.0.6",
"rxjs": ">=6.0.0"
}
},
"node_modules/@taiga-ui/icons": {
- "version": "3.73.0",
- "resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-3.73.0.tgz",
- "integrity": "sha512-3/B9NW/gQ4ad+voS57TSuz7cCElh1hcqUil4wP2P8pwS3HzgScokZpvVQs6u5jZ0Xt4v7uG4pac6pwGVsC8ndA==",
+ "version": "3.77.1",
+ "resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-3.77.1.tgz",
+ "integrity": "sha512-e9NXwxOktKM9TVDVePVkTFAuAs9jlhZCKzpAOfrme1bHVQJ1MEhD2hdj74Yn7IGKOCFjrUDQnxJ9w9POh6H9Vg==",
"dependencies": {
- "tslib": "2.6.2"
+ "tslib": "^2.6.2"
},
"peerDependencies": {
- "@taiga-ui/cdk": "^3.73.0"
+ "@taiga-ui/cdk": "^3.77.1"
}
},
"node_modules/@taiga-ui/kit": {
- "version": "3.73.0",
- "resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-3.73.0.tgz",
- "integrity": "sha512-AKPjxkcKnMA4TeL5f6gBjgnJff7JJfh2YmOxHPcXXcBy/BeXzY+Lfmlgqz0P8Rtz01JouCZpWIWNayb2cGlq5g==",
+ "version": "3.77.1",
+ "resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-3.77.1.tgz",
+ "integrity": "sha512-Pyk44wDF61VZiMQHehQ3KEEBj5AsO3et8QccKwmqr13jaQzmH6ljwbbYJOwPpEVsdZbqfiI56OVxp86mi6F8mw==",
"dependencies": {
"@maskito/angular": "1.9.0",
"@maskito/core": "1.9.0",
"@maskito/kit": "1.9.0",
"@ng-web-apis/intersection-observer": "3.2.0",
"text-mask-core": "5.1.2",
- "tslib": "2.6.2"
+ "tslib": "^2.6.2"
},
"peerDependencies": {
"@angular/common": ">=12.0.0",
@@ -5255,22 +5255,22 @@
"@angular/forms": ">=12.0.0",
"@angular/router": ">=12.0.0",
"@ng-web-apis/common": "3.0.6",
- "@ng-web-apis/mutation-observer": "3.1.0",
- "@ng-web-apis/resize-observer": "3.0.6",
- "@taiga-ui/cdk": "^3.73.0",
- "@taiga-ui/core": "^3.73.0",
- "@taiga-ui/i18n": "^3.73.0",
- "@tinkoff/ng-polymorpheus": "4.3.0",
+ "@ng-web-apis/mutation-observer": "^3.1.0",
+ "@ng-web-apis/resize-observer": "^3.0.6",
+ "@taiga-ui/cdk": "^3.77.1",
+ "@taiga-ui/core": "^3.77.1",
+ "@taiga-ui/i18n": "^3.77.1",
+ "@tinkoff/ng-polymorpheus": "^4.3.0",
"rxjs": ">=6.0.0"
}
},
"node_modules/@taiga-ui/styles": {
- "version": "3.73.0",
- "resolved": "https://registry.npmjs.org/@taiga-ui/styles/-/styles-3.73.0.tgz",
- "integrity": "sha512-hFInEKxsI4fj5KZCIGzH/zY00YwE2PsUoAlzoeGqpfnOG5rY/2WFpZnLrj7yJCOkFzsFy9KUZC00d46w50ijnQ==",
+ "version": "3.77.1",
+ "resolved": "https://registry.npmjs.org/@taiga-ui/styles/-/styles-3.77.1.tgz",
+ "integrity": "sha512-YoPXqY1pz+13vYhHnE6hskjRtnDDGgjnZIPtx05ChN8/TDIJ6NiaWKI5Es/G4fq3vKJnq2yIZ9D2Ghm/aPItGw==",
"peerDependencies": {
- "@taiga-ui/cdk": "^3.73.0",
- "tslib": "2.6.2"
+ "@taiga-ui/cdk": "^3.77.1",
+ "tslib": "^2.6.2"
}
},
"node_modules/@tinkoff/ng-dompurify": {
@@ -5287,9 +5287,9 @@
}
},
"node_modules/@tinkoff/ng-event-plugins": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@tinkoff/ng-event-plugins/-/ng-event-plugins-3.1.1.tgz",
- "integrity": "sha512-JC64sdpiOHmq4rZBFzqVweQoPxN7afoCuebKayEELEODho6oYiTVyM3P9T9JWUyzieSujDP7um7fiCggrWc83A==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@tinkoff/ng-event-plugins/-/ng-event-plugins-3.2.0.tgz",
+ "integrity": "sha512-n56R5xNfiytabh2WmWdQXfNU6m7dfOo3LLxlARE+DX7f5yciW2xBdDkuEHX74q8dlCuAVlW9aslSfz8c//ymwA==",
"dependencies": {
"tslib": "^2.2.0"
},
diff --git a/web/package.json b/web/package.json
index eeb0a5000..dea30cefb 100644
--- a/web/package.json
+++ b/web/package.json
@@ -45,17 +45,17 @@
"@start9labs/argon2": "^0.1.0",
"@start9labs/emver": "^0.1.5",
"@start9labs/start-sdk": "file:../sdk/dist",
- "@taiga-ui/addon-charts": "3.73.0",
- "@taiga-ui/addon-commerce": "3.73.0",
- "@taiga-ui/addon-mobile": "3.73.0",
- "@taiga-ui/cdk": "3.73.0",
- "@taiga-ui/core": "3.73.0",
- "@taiga-ui/experimental": "3.73.0",
- "@taiga-ui/icons": "3.73.0",
- "@taiga-ui/kit": "3.73.0",
- "@taiga-ui/styles": "3.73.0",
+ "@taiga-ui/addon-charts": "3.77.1",
+ "@taiga-ui/addon-commerce": "3.77.1",
+ "@taiga-ui/addon-mobile": "3.77.1",
+ "@taiga-ui/cdk": "3.77.1",
+ "@taiga-ui/core": "3.77.1",
+ "@taiga-ui/experimental": "3.77.1",
+ "@taiga-ui/icons": "3.77.1",
+ "@taiga-ui/kit": "3.77.1",
+ "@taiga-ui/styles": "3.77.1",
"@tinkoff/ng-dompurify": "4.0.0",
- "@tinkoff/ng-event-plugins": "3.1.1",
+ "@tinkoff/ng-event-plugins": "3.2.0",
"ansi-to-html": "^0.7.2",
"base64-js": "^1.5.1",
"cbor": "npm:@jprochazk/cbor@^0.4.9",
diff --git a/web/projects/marketplace/src/pages/show/additional/additional.component.scss b/web/projects/marketplace/src/pages/show/additional/additional.component.scss
index 0a8c0e199..c8c41396e 100644
--- a/web/projects/marketplace/src/pages/show/additional/additional.component.scss
+++ b/web/projects/marketplace/src/pages/show/additional/additional.component.scss
@@ -10,7 +10,7 @@
& > * + * {
border-top-width: 1px;
- border-bottom-width: 0px;
+ border-bottom-width: 0;
border-color: rgb(113 113 122);
}
}
diff --git a/web/projects/shared/styles/taiga.scss b/web/projects/shared/styles/taiga.scss
index 5adcc6739..c68065da5 100644
--- a/web/projects/shared/styles/taiga.scss
+++ b/web/projects/shared/styles/taiga.scss
@@ -9,7 +9,7 @@
/* stylelint-disable order/order */
[tuiAppearance][data-appearance='secondary-warning'] {
background: var(--tui-warning-bg);
- color: var(--tui-warning-fill);
+ color: var(--tui-text-01);
@include appearance-hover {
background: var(--tui-warning-bg-hover);
@@ -58,6 +58,7 @@
@include appearance-disabled {
background: #eaecee;
+ color: #333;
}
}
@@ -75,6 +76,7 @@
@include appearance-disabled {
background: #eaecee;
+ color: #333;
}
}
@@ -92,6 +94,7 @@
@include appearance-disabled {
background: #eaecee;
+ color: #333;
}
}
@@ -109,6 +112,7 @@
@include appearance-disabled {
background: #eaecee;
+ color: #333;
}
}
@@ -126,6 +130,7 @@
@include appearance-disabled {
background: #eaecee;
+ color: #333;
}
}
diff --git a/web/projects/ui/src/app/routes/portal/components/form/form-object/form-object.component.html b/web/projects/ui/src/app/routes/portal/components/form/form-object/form-object.component.html
index aa9e85f19..6dccad33a 100644
--- a/web/projects/ui/src/app/routes/portal/components/form/form-object/form-object.component.html
+++ b/web/projects/ui/src/app/routes/portal/components/form/form-object/form-object.component.html
@@ -7,7 +7,7 @@
class="button"
[class.button_open]="open"
[style.border-radius.%]="100"
- [appearance]="invalid ? 'secondary-destructive' : 'secondary'"
+ [appearance]="invalid ? 'danger-solid' : 'secondary'"
>
{{ spec.name }}
diff --git a/web/projects/ui/src/app/routes/portal/routes/service/components/action.component.ts b/web/projects/ui/src/app/routes/portal/routes/service/components/action.component.ts
index 5861b0fd0..fe6e30bec 100644
--- a/web/projects/ui/src/app/routes/portal/routes/service/components/action.component.ts
+++ b/web/projects/ui/src/app/routes/portal/routes/service/components/action.component.ts
@@ -1,5 +1,6 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { TuiSvgModule } from '@taiga-ui/core'
+import { TuiIconModule } from '@taiga-ui/experimental'
interface ActionItem {
readonly icon: string
@@ -10,7 +11,7 @@ interface ActionItem {
@Component({
selector: '[action]',
template: `
-
+
{{ action.name }}
{{ action.description }}
@@ -18,7 +19,7 @@ interface ActionItem {
`,
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
- imports: [TuiSvgModule],
+ imports: [TuiIconModule],
})
export class ServiceActionComponent {
@Input({ required: true })
diff --git a/web/projects/ui/src/app/routes/portal/routes/service/components/actions.component.ts b/web/projects/ui/src/app/routes/portal/routes/service/components/actions.component.ts
index 14889dcad..696c46620 100644
--- a/web/projects/ui/src/app/routes/portal/routes/service/components/actions.component.ts
+++ b/web/projects/ui/src/app/routes/portal/routes/service/components/actions.component.ts
@@ -4,13 +4,16 @@ import {
inject,
Input,
} from '@angular/core'
+import { Manifest } from '@startos'
import { tuiPure } from '@taiga-ui/cdk'
-import { TuiButtonModule } from '@taiga-ui/experimental'
+import {
+ TuiButtonModule,
+ tuiButtonOptionsProvider,
+} from '@taiga-ui/experimental'
import { DependencyInfo } from 'src/app/routes/portal/routes/service/types/dependency-info'
import { ActionsService } from 'src/app/services/actions.service'
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
import { getManifest } from 'src/app/utils/get-package-data'
-import { Manifest } from '../../../../../../../../../../core/startos/bindings/Manifest'
@Component({
selector: 'service-actions',
@@ -18,7 +21,7 @@ import { Manifest } from '../../../../../../../../../../core/startos/bindings/Ma
@if (pkg.status.main.status === 'running') {
@@ -75,7 +75,7 @@ export class ServiceActionsRoute {
.pipe(filter(pkg => pkg.stateInfo.state === 'installed'))
readonly action = {
- icon: 'tuiIconTrash2Large',
+ icon: 'tuiIconTrash2',
name: 'Uninstall',
description:
'This will uninstall the service from StartOS and delete all data permanently.',
diff --git a/web/projects/ui/src/app/routes/portal/routes/service/routes/service.component.ts b/web/projects/ui/src/app/routes/portal/routes/service/routes/service.component.ts
index a1e4e7001..8b96919d6 100644
--- a/web/projects/ui/src/app/routes/portal/routes/service/routes/service.component.ts
+++ b/web/projects/ui/src/app/routes/portal/routes/service/routes/service.component.ts
@@ -2,8 +2,15 @@ import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router'
import { isEmptyObject } from '@start9labs/shared'
+import { HealthCheckResult, MainStatus, Manifest } from '@startos'
import { PatchDB } from 'patch-db-client'
import { combineLatest, map, switchMap } from 'rxjs'
+import {
+ ConfigModal,
+ PackageConfigData,
+} from 'src/app/routes/portal/modals/config.component'
+import { ServiceBackupsComponent } from 'src/app/routes/portal/routes/service/components/backups.component'
+import { InstallingProgressPipe } from 'src/app/routes/portal/routes/service/pipes/install-progress.pipe'
import { ConnectionService } from 'src/app/services/connection.service'
import {
DepErrorService,
@@ -21,87 +28,122 @@ import {
StatusRendering,
} from 'src/app/services/pkg-status-rendering.service'
import { DependentInfo } from 'src/app/types/dependent-info'
+import { getManifest } from 'src/app/utils/get-package-data'
import { ServiceActionsComponent } from '../components/actions.component'
-import { ServiceAdditionalComponent } from '../components/additional.component'
import { ServiceDependenciesComponent } from '../components/dependencies.component'
import { ServiceHealthChecksComponent } from '../components/health-checks.component'
import { ServiceInterfaceListComponent } from '../components/interface-list.component'
import { ServiceMenuComponent } from '../components/menu.component'
import { ServiceProgressComponent } from '../components/progress.component'
import { ServiceStatusComponent } from '../components/status.component'
-import {
- PackageConfigData,
- ConfigModal,
-} from 'src/app/routes/portal/modals/config.component'
import { DependencyInfo } from '../types/dependency-info'
-import { getManifest } from 'src/app/utils/get-package-data'
-import { InstallingProgressPipe } from 'src/app/routes/portal/routes/service/pipes/install-progress.pipe'
-import { Manifest } from '../../../../../../../../../../core/startos/bindings/Manifest'
-import { HealthCheckResult } from '../../../../../../../../../../core/startos/bindings/HealthCheckResult'
-import { MainStatus } from '../../../../../../../../../../core/startos/bindings/MainStatus'
@Component({
template: `
@if (service$ | async; as service) {
-
Status
-
-
- @if (
- service.pkg.stateInfo.state === 'installing' ||
- service.pkg.stateInfo.state === 'updating' ||
- service.pkg.stateInfo.state === 'restoring'
- ) {
-
+
Status
+
- {{ phase.name }}
-
- } @else {
- @if (
- service.pkg.stateInfo.state === 'installed' &&
- service.status.primary !== 'backingUp'
- ) {
- @if (connected$ | async) {
-
- }
+ />
+ @if (isInstalled(service) && (connected$ | async)) {
+
+ }
+
+
+ @if (isInstalled(service)) {
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
- @if (
- service.status.primary === 'running' && (health$ | async);
- as checks
- ) {
-
- }
-
- @if (service.dependencies.length) {
-
- }
-
-
-
+ @if (isInstalling(service.pkg.stateInfo.state)) {
+ @for (
+ item of service.pkg.stateInfo.installingInfo?.progress?.phases;
+ track $index
+ ) {
+ {{ item.name }}
}
}
}
`,
+ styles: `
+ :host {
+ display: grid;
+ grid-template-columns: repeat(12, 1fr);
+ flex-direction: column;
+ gap: 1rem;
+ margin: 1rem -1rem 0;
+ }
+
+ :host-context(tui-root._mobile) {
+ display: flex;
+ }
+
+ section {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ padding: 1rem 1.5rem 0.5rem;
+ border-radius: 1rem;
+ background: var(--tui-clear);
+ box-shadow: inset 0 7rem 0 -4rem var(--tui-clear);
+ clip-path: polygon(0 1.5rem, 1.5rem 0, 100% 0, 100% 100%, 0 100%);
+ }
+
+ h3 {
+ margin-bottom: 1.25rem;
+ }
+
+ div {
+ display: flex;
+ flex-direction: column;
+ gap: inherit;
+ grid-column: span 4;
+ }
+ `,
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [
@@ -113,7 +155,7 @@ import { MainStatus } from '../../../../../../../../../../core/startos/bindings/
ServiceHealthChecksComponent,
ServiceDependenciesComponent,
ServiceMenuComponent,
- ServiceAdditionalComponent,
+ ServiceBackupsComponent,
InstallingProgressPipe,
],
})
@@ -134,13 +176,11 @@ export class ServiceRoute {
this.depErrorService.getPkgDepErrors$(pkgId),
]),
),
- map(([pkg, depErrors]) => {
- return {
- pkg,
- dependencies: this.getDepInfo(pkg, depErrors),
- status: renderPkgStatus(pkg, depErrors),
- }
- }),
+ map(([pkg, depErrors]) => ({
+ pkg,
+ dependencies: this.getDepInfo(pkg, depErrors),
+ status: renderPkgStatus(pkg, depErrors),
+ })),
)
readonly health$ = this.pkgId$.pipe(
@@ -150,6 +190,16 @@ export class ServiceRoute {
map(toHealthCheck),
)
+ isInstalling(state: string): boolean {
+ return (
+ state === 'installing' || state === 'updating' || state === 'restoring'
+ )
+ }
+
+ isInstalled({ pkg, status }: any): boolean {
+ return pkg.stateInfo.state === 'installed' && status.primary !== 'backingUp'
+ }
+
getRendering({ primary }: PackageStatus): StatusRendering {
return PrimaryRendering[primary]
}
@@ -160,9 +210,9 @@ export class ServiceRoute {
): DependencyInfo[] {
const manifest = getManifest(pkg)
- return Object.keys(pkg.currentDependencies)
- .filter(id => !!manifest.dependencies[id])
- .map(id => this.getDepValues(pkg, manifest, id, depErrors))
+ return Object.keys(pkg.currentDependencies).map(id =>
+ this.getDepValues(pkg, manifest, id, depErrors),
+ )
}
private getDepValues(
@@ -203,7 +253,7 @@ export class ServiceRoute {
depId: string,
depErrors: PkgDependencyErrors,
) {
- const depError = depErrors[pkgManifest.id]
+ const depError = depErrors[depId]
let errorText: string | null = null
let fixText: string | null = null
@@ -271,10 +321,15 @@ export class ServiceRoute {
version: pkg.currentDependencies[depId].versionSpec,
}
const navigationExtras: NavigationExtras = {
+ // @TODO state not being used by marketplace component. Maybe it is not important to use.
state: { dependentInfo },
+ queryParams: { id: depId },
}
- await this.router.navigate(['marketplace', depId], navigationExtras)
+ await this.router.navigate(
+ ['portal', 'system', 'marketplace'],
+ navigationExtras,
+ )
}
}
diff --git a/web/projects/ui/src/app/routes/portal/routes/system/backups/modals/history.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/backups/modals/history.component.ts
index 1a44c2322..a91bb1a7b 100644
--- a/web/projects/ui/src/app/routes/portal/routes/system/backups/modals/history.component.ts
+++ b/web/projects/ui/src/app/routes/portal/routes/system/backups/modals/history.component.ts
@@ -26,7 +26,7 @@ import { GetBackupIconPipe } from '../pipes/get-backup-icon.pipe'
Past Events
diff --git a/web/projects/ui/src/app/routes/portal/routes/system/notifications/item.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/notifications/item.component.ts
index b1fc15ccd..2a05182e7 100644
--- a/web/projects/ui/src/app/routes/portal/routes/system/notifications/item.component.ts
+++ b/web/projects/ui/src/app/routes/portal/routes/system/notifications/item.component.ts
@@ -2,20 +2,20 @@ import { CommonModule } from '@angular/common'
import {
ChangeDetectionStrategy,
Component,
- Input,
inject,
+ Input,
} from '@angular/core'
import { RouterLink } from '@angular/router'
+import { Manifest } from '@startos'
import { tuiPure } from '@taiga-ui/cdk'
import { TuiSvgModule } from '@taiga-ui/core'
import { TuiLineClampModule } from '@taiga-ui/kit'
import { PatchDB } from 'patch-db-client'
-import { Observable, first } from 'rxjs'
+import { first, Observable } from 'rxjs'
import { ServerNotification } from 'src/app/services/api/api.types'
-import { DataModel } from 'src/app/services/patch-db/data-model'
import { NotificationService } from 'src/app/services/notification.service'
+import { DataModel } from 'src/app/services/patch-db/data-model'
import { toRouterLink } from 'src/app/utils/to-router-link'
-import { Manifest } from '../../../../../../../../../../core/startos/bindings/Manifest'
@Component({
selector: '[notificationItem]',
diff --git a/web/projects/ui/src/app/services/actions.service.ts b/web/projects/ui/src/app/services/actions.service.ts
index 04b187743..613f09f61 100644
--- a/web/projects/ui/src/app/services/actions.service.ts
+++ b/web/projects/ui/src/app/services/actions.service.ts
@@ -1,19 +1,19 @@
import { inject, Injectable } from '@angular/core'
import { ErrorService, LoadingService } from '@start9labs/shared'
+import { Manifest } from '@startos'
import { TuiDialogOptions, TuiDialogService } from '@taiga-ui/core'
import { TUI_PROMPT, TuiPromptData } from '@taiga-ui/kit'
+import { PatchDB } from 'patch-db-client'
import { defaultIfEmpty, filter, firstValueFrom } from 'rxjs'
import {
- PackageConfigData,
ConfigModal,
+ PackageConfigData,
} from 'src/app/routes/portal/modals/config.component'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { FormDialogService } from 'src/app/services/form-dialog.service'
import { DataModel } from 'src/app/services/patch-db/data-model'
-import { hasCurrentDeps } from 'src/app/utils/has-deps'
import { getAllPackages } from 'src/app/utils/get-package-data'
-import { PatchDB } from 'patch-db-client'
-import { Manifest } from '../../../../../../core/startos/bindings/Manifest'
+import { hasCurrentDeps } from 'src/app/utils/has-deps'
@Injectable({
providedIn: 'root',
diff --git a/web/projects/ui/src/app/services/api/api.fixures.ts b/web/projects/ui/src/app/services/api/api.fixures.ts
index b62f73e28..87d14abaf 100644
--- a/web/projects/ui/src/app/services/api/api.fixures.ts
+++ b/web/projects/ui/src/app/services/api/api.fixures.ts
@@ -913,7 +913,7 @@ export module Mock {
integer: false,
}),
}),
- displayAs: 'I\'m {{last-name}}, {{first-name}} {{last-name}}',
+ displayAs: `I'm {{last-name}}, {{first-name}} {{last-name}}`,
uniqueBy: 'last-name',
},
),
@@ -1295,6 +1295,7 @@ export module Mock {
icon: '/assets/img/service-icons/bitcoind.svg',
installedAt: new Date().toISOString(),
lastBackup: null,
+ nextBackup: null,
status: {
configured: true,
main: {
@@ -1539,6 +1540,7 @@ export module Mock {
icon: '/assets/img/service-icons/btc-rpc-proxy.png',
installedAt: new Date().toISOString(),
lastBackup: null,
+ nextBackup: null,
status: {
configured: false,
main: {
@@ -1681,6 +1683,7 @@ export module Mock {
icon: '/assets/img/service-icons/lnd.png',
installedAt: new Date().toISOString(),
lastBackup: null,
+ nextBackup: null,
status: {
configured: true,
main: {
diff --git a/web/projects/ui/src/app/services/api/mock-patch.ts b/web/projects/ui/src/app/services/api/mock-patch.ts
index 8cb16e8fa..6d04898a2 100644
--- a/web/projects/ui/src/app/services/api/mock-patch.ts
+++ b/web/projects/ui/src/app/services/api/mock-patch.ts
@@ -146,7 +146,8 @@ export const mockPatchData: DataModel = {
},
icon: '/assets/img/service-icons/bitcoind.svg',
installedAt: new Date().toISOString(),
- lastBackup: null,
+ lastBackup: new Date(new Date().valueOf() - 604800001).toISOString(),
+ nextBackup: new Date(new Date().valueOf() + 100000000).toISOString(),
status: {
configured: true,
main: {
@@ -419,6 +420,7 @@ export const mockPatchData: DataModel = {
icon: '/assets/img/service-icons/lnd.png',
installedAt: new Date().toISOString(),
lastBackup: null,
+ nextBackup: null,
status: {
configured: true,
main: {
diff --git a/web/projects/ui/src/app/services/patch-db/data-model.ts b/web/projects/ui/src/app/services/patch-db/data-model.ts
index 072b9d254..b3cf2dc2c 100644
--- a/web/projects/ui/src/app/services/patch-db/data-model.ts
+++ b/web/projects/ui/src/app/services/patch-db/data-model.ts
@@ -131,6 +131,7 @@ export type PackageDataEntry =
stateInfo: T
installedAt: string
outboundProxy: string | null
+ nextBackup: string | null
}
export type StateInfo = InstalledState | InstallingState | UpdatingState
diff --git a/web/tsconfig.json b/web/tsconfig.json
index 9b4b79b35..6ea5ae52e 100644
--- a/web/tsconfig.json
+++ b/web/tsconfig.json
@@ -23,7 +23,8 @@
"paths": {
/* These paths are relative to each app base folder */
"@start9labs/marketplace": ["../marketplace/index"],
- "@start9labs/shared": ["../shared/src/public-api"]
+ "@start9labs/shared": ["../shared/src/public-api"],
+ "@startos": ["../../../core/startos/bindings/index"]
},
"typeRoots": ["node_modules/@types"],
"types": ["node"]