Skip to content

Commit

Permalink
Action Request updates + misc fixes (#2818)
Browse files Browse the repository at this point in the history
* fix web manifest format error

* fix setting optional dependencies

* rework dependency actions to be nested

* fix styling

* fix styles

* combine action requests into same component

* only display actions header if they exist

* fix storing polyfill dependencies

* fix styling and button propagation

* fixes for setting polyfill dependencies

* revert to test

* revert required deps setting logic

* add logs and adjust logic

* test

* fix deps logic when changing config

* remove logs; deps working as expected
  • Loading branch information
elvece authored Feb 9, 2025
1 parent 4e22f13 commit 3047dae
Show file tree
Hide file tree
Showing 14 changed files with 326 additions and 137 deletions.
10 changes: 5 additions & 5 deletions container-runtime/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 29 additions & 29 deletions container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ function todo(): never {
const MANIFEST_LOCATION = "/usr/lib/startos/package/embassyManifest.json"
export const EMBASSY_JS_LOCATION = "/usr/lib/startos/package/embassy.js"
const EMBASSY_POINTER_PATH_PREFIX = "/embassyConfig" as utils.StorePath
const EMBASSY_DEPENDS_ON_PATH_PREFIX = "/embassyDependsOn" as utils.StorePath

const matchResult = object({
result: any,
Expand Down Expand Up @@ -314,7 +315,7 @@ export class SystemForEmbassy implements System {
)
.catch(() => []),
)
await this.setDependencies(effects, oldDeps)
await this.setDependencies(effects, oldDeps, false)
}

async exit(): Promise<void> {
Expand Down Expand Up @@ -664,7 +665,7 @@ export class SystemForEmbassy implements System {
),
)
const dependsOn = answer["depends-on"] ?? answer.dependsOn ?? {}
await this.setDependencies(effects, dependsOn)
await this.setDependencies(effects, dependsOn, true)
return
} else if (setConfigValue.type === "script") {
const moduleCode = await this.moduleCode
Expand All @@ -687,48 +688,47 @@ export class SystemForEmbassy implements System {
}),
)
const dependsOn = answer["depends-on"] ?? answer.dependsOn ?? {}
await this.setDependencies(effects, dependsOn)
await this.setDependencies(effects, dependsOn, true)
return
}
}
private async setDependencies(
effects: Effects,
rawDepends: { [x: string]: readonly string[] },
configuring: boolean,
) {
const dependsOn: Record<string, readonly string[] | null> = {
const storedDependsOn = (await effects.store.get({
packageId: this.manifest.id,
path: EMBASSY_DEPENDS_ON_PATH_PREFIX,
})) as Record<string, readonly string[]>

const requiredDeps = {
...Object.fromEntries(
Object.entries(this.manifest.dependencies || {})?.map((x) => [
x[0],
null,
]) || [],
Object.entries(this.manifest.dependencies || {})
?.filter((x) => x[1].requirement.type === "required")
.map((x) => [x[0], []]) || [],
),
...rawDepends,
}

const dependsOn: Record<string, readonly string[]> = configuring
? {
...requiredDeps,
...rawDepends,
}
: storedDependsOn
? storedDependsOn
: requiredDeps

await effects.store.set({
path: EMBASSY_DEPENDS_ON_PATH_PREFIX,
value: dependsOn,
})

await effects.setDependencies({
dependencies: Object.entries(dependsOn).flatMap(
([key, value]): T.Dependencies => {
const dependency = this.manifest.dependencies?.[key]
if (!dependency) return []
if (value == null) {
const versionRange = dependency.version
if (dependency.requirement.type === "required") {
return [
{
id: key,
versionRange,
kind: "running",
healthChecks: [],
},
]
}
return [
{
kind: "exists",
id: key,
versionRange,
},
]
}
const versionRange = dependency.version
const kind = "running"
return [
Expand Down
4 changes: 2 additions & 2 deletions container-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ new RpcListener(getDependencies)

/**
So, this is going to be sent into a running comtainer along with any of the other node modules that are going to be needed and used.
So, this is going to be sent into a running container along with any of the other node modules that are going to be needed and used.
Once the container is started, we will go into a loading/ await state.
This is the init system, and it will always be running, and it will be waiting for a command to be sent to it.
Expand All @@ -38,5 +38,5 @@ There are

/**
TODO:
Should I seperate those adapter in/out?
Should I separate those adapter in/out?
*/
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
<app-show-dependencies
*ngIf="pkgPlus.dependencies.length"
[dependencies]="pkgPlus.dependencies"
[allPkgs]="pkgPlus.allPkgs"
[pkg]="pkg"
[manifest]="pkgPlus.manifest"
></app-show-dependencies>
<!-- ** menu ** -->
<app-show-menu [buttons]="pkg | toButtons"></app-show-menu>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export class AppShowPage {
fixText = 'Update'
fixAction = () => this.installDep(pkg, manifest, depId)
} else if (depError.type === 'actionRequired') {
errorText = 'Action Required (see above)'
errorText = 'Action Required (see below)'
} else if (depError.type === 'notRunning') {
errorText = 'Not running'
fixText = 'Start'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,45 +1,42 @@
<ng-container *ngIf="actionRequests.critical.length">
<ion-item-divider>Required Actions</ion-item-divider>
<ion-item
*ngFor="let request of actionRequests.critical"
button
(click)="handleAction(request)"
<ng-container *ngIf="actionRequests[pkgId]?.length">
<ion-item-divider
*ngIf="!dep"
style="--background: unset; z-index: 11; position: relative"
>
<ion-icon slot="start" name="warning-outline" color="warning"></ion-icon>
<ion-label>
<h2 class="highlighted">{{ request.actionName }}</h2>
<p *ngIf="request.dependency" class="dependency">
<span class="light">Service:</span>
<img [src]="request.dependency.icon" alt="" />
{{ request.dependency.title }}
</p>
<p>
<span class="light">Reason:</span>
{{ request.reason || 'no reason provided' }}
</p>
</ion-label>
</ion-item>
</ng-container>

<ng-container *ngIf="actionRequests.important.length">
<ion-item-divider>Requested Actions</ion-item-divider>
<ion-item
*ngFor="let request of actionRequests.important"
button
(click)="handleAction(request)"
>
<ion-icon slot="start" name="play-outline" color="warning"></ion-icon>
<ion-label>
<h2 class="highlighted">{{ request.actionName }}</h2>
<p *ngIf="request.dependency" class="dependency">
<span class="light">Service:</span>
<img [src]="request.dependency.icon" alt="" />
{{ request.dependency.title }}
</p>
<p>
<span class="light">Reason:</span>
{{ request.reason || 'no reason provided' }}
</p>
</ion-label>
</ion-item>
Action Requests
</ion-item-divider>
<div class="indent">
<ion-item
class="line"
lines="none"
*ngFor="let request of actionRequests[pkgId]"
button
(click)="handleAction(request, $event)"
>
<ion-icon
slot="start"
[name]="
request.severity === 'critical' ? 'warning-outline' : 'play-outline'
"
[color]="request.severity === 'critical' ? 'warning' : 'dark'"
></ion-icon>
<ion-label>
<h2 class="highlighted">{{ request.actionName }}</h2>
<p>
{{ request.reason || 'no reason provided' }} |
<span
class="severity"
[ngStyle]="{
color:
request.severity === 'critical'
? 'var(--ion-color-warning)'
: 'var(--ion-color-dark)'
}"
>
{{ request.severity === 'critical' ? 'Required' : 'Requested' }}
</span>
</p>
</ion-label>
</ion-item>
</div>
</ng-container>
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
.light {
color: var(--ion-color-dark);
ion-icon {
margin-right: 32px;
}

.highlighted {
color: var(--ion-color-dark);
font-weight: bold;
}

.dependency {
display: inline-flex;
img {
max-width: 16px;
margin: 0 2px 0 5px;
.severity {
font-variant-caps: all-small-caps;
font-weight: bold;
letter-spacing: 0.2px;
font-size: 16px;
}

.line {

&:after {
content: '';
display: block;
border-left: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
height: 100%;
width: 24px;
position: absolute;
left: -20px;
top: -33px;
}
}

.indent {
margin-left: 41px
}

:host ::ng-deep ion-item {
display: table-row;
width: fit-content;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { T } from '@start9labs/start-sdk'
import { ActionService } from 'src/app/services/action.service'
import { DependencyInfo } from 'src/app/pages/apps-routes/app-show/app-show.page'
import { getDepDetails } from 'src/app/util/dep-info'

@Component({
Expand All @@ -19,22 +20,21 @@ export class AppShowActionRequestsComponent {
@Input()
manifest!: T.Manifest

get actionRequests() {
const critical: (T.ActionRequest & {
actionName: string
dependency: {
title: string
icon: string
} | null
})[] = []
const important: (T.ActionRequest & {
actionName: string
dependency: {
title: string
icon: string
} | null
})[] = []
@Input()
dep?: DependencyInfo

pkgId!: string

ngOnInit() {
this.pkgId = this.dep ? this.dep?.id : this.manifest.id
}

get actionRequests() {
const reqs: {
[key: string]: (T.ActionRequest & {
actionName: string
})[]
} = {}
Object.values(this.pkg.requestedActions)
.filter(r => r.active)
.forEach(r => {
Expand All @@ -49,20 +49,17 @@ export class AppShowActionRequestsComponent {
? null
: getDepDetails(this.pkg, this.allPkgs, r.request.packageId),
}

if (r.request.severity === 'critical') {
critical.push(toReturn)
} else {
important.push(toReturn)
if (!reqs[r.request.packageId]) {
reqs[r.request.packageId] = []
}
reqs[r.request.packageId].push(toReturn)
})

return { critical, important }
return reqs
}

constructor(private readonly actionService: ActionService) {}

async handleAction(request: T.ActionRequest) {
async handleAction(request: T.ActionRequest, e: Event) {
e.stopPropagation()
const self = request.packageId === this.manifest.id
this.actionService.present({
pkgInfo: {
Expand Down
Loading

0 comments on commit 3047dae

Please sign in to comment.