mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
feat: split row_actions into remove_action and overflow_actions for URL plugins
This commit is contained in:
2
Makefile
2
Makefile
@@ -278,7 +278,7 @@ core/bindings/index.ts: $(call ls-files, core) $(ENVIRONMENT_FILE)
|
|||||||
rm -rf core/bindings
|
rm -rf core/bindings
|
||||||
./core/build/build-ts.sh
|
./core/build/build-ts.sh
|
||||||
ls core/bindings/*.ts | sed 's/core\/bindings\/\([^.]*\)\.ts/export { \1 } from ".\/\1";/g' | grep -v '"./index"' | tee core/bindings/index.ts
|
ls core/bindings/*.ts | sed 's/core\/bindings\/\([^.]*\)\.ts/export { \1 } from ".\/\1";/g' | grep -v '"./index"' | tee core/bindings/index.ts
|
||||||
npm --prefix sdk exec -- prettier --config ./sdk/base/package.json -w ./core/bindings/*.ts
|
npm --prefix sdk/base exec -- prettier --config=./sdk/base/package.json -w ./core/bindings/*.ts
|
||||||
touch core/bindings/index.ts
|
touch core/bindings/index.ts
|
||||||
|
|
||||||
sdk/dist/package.json sdk/baseDist/package.json: $(call ls-files, sdk) sdk/base/lib/osBindings/index.ts
|
sdk/dist/package.json sdk/baseDist/package.json: $(call ls-files, sdk) sdk/base/lib/osBindings/index.ts
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ pub enum HostnameMetadata {
|
|||||||
},
|
},
|
||||||
Plugin {
|
Plugin {
|
||||||
package_id: PackageId,
|
package_id: PackageId,
|
||||||
row_actions: Vec<ActionId>,
|
remove_action: Option<ActionId>,
|
||||||
|
overflow_actions: Vec<ActionId>,
|
||||||
#[ts(type = "unknown")]
|
#[ts(type = "unknown")]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
info: Value,
|
info: Value,
|
||||||
@@ -99,7 +100,8 @@ impl PluginHostnameInfo {
|
|||||||
pub fn to_hostname_info(
|
pub fn to_hostname_info(
|
||||||
&self,
|
&self,
|
||||||
plugin_package: &PackageId,
|
plugin_package: &PackageId,
|
||||||
row_actions: Vec<ActionId>,
|
remove_action: Option<ActionId>,
|
||||||
|
overflow_actions: Vec<ActionId>,
|
||||||
) -> HostnameInfo {
|
) -> HostnameInfo {
|
||||||
HostnameInfo {
|
HostnameInfo {
|
||||||
ssl: self.ssl,
|
ssl: self.ssl,
|
||||||
@@ -109,7 +111,8 @@ impl PluginHostnameInfo {
|
|||||||
metadata: HostnameMetadata::Plugin {
|
metadata: HostnameMetadata::Plugin {
|
||||||
package_id: plugin_package.clone(),
|
package_id: plugin_package.clone(),
|
||||||
info: self.info.clone(),
|
info: self.info.clone(),
|
||||||
row_actions,
|
remove_action,
|
||||||
|
overflow_actions,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +121,9 @@ impl PluginHostnameInfo {
|
|||||||
/// (comparing address fields only, not row_actions).
|
/// (comparing address fields only, not row_actions).
|
||||||
pub fn matches_hostname_info(&self, h: &HostnameInfo, plugin_package: &PackageId) -> bool {
|
pub fn matches_hostname_info(&self, h: &HostnameInfo, plugin_package: &PackageId) -> bool {
|
||||||
match &h.metadata {
|
match &h.metadata {
|
||||||
HostnameMetadata::Plugin { package_id, info, .. } => {
|
HostnameMetadata::Plugin {
|
||||||
|
package_id, info, ..
|
||||||
|
} => {
|
||||||
package_id == plugin_package
|
package_id == plugin_package
|
||||||
&& h.ssl == self.ssl
|
&& h.ssl == self.ssl
|
||||||
&& h.public == self.public
|
&& h.public == self.public
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ fn require_url_plugin(context: &Arc<Service>) -> Result<(), Error> {
|
|||||||
.contains(&PluginId::UrlV0)
|
.contains(&PluginId::UrlV0)
|
||||||
{
|
{
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
eyre!("{}", t!("net.plugin.manifest-missing-plugin", plugin = "url-v0")),
|
eyre!(
|
||||||
|
"{}",
|
||||||
|
t!("net.plugin.manifest-missing-plugin", plugin = "url-v0")
|
||||||
|
),
|
||||||
ErrorKind::InvalidRequest,
|
ErrorKind::InvalidRequest,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -68,36 +71,45 @@ pub async fn register(
|
|||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
pub struct UrlPluginExportUrlParams {
|
pub struct UrlPluginExportUrlParams {
|
||||||
pub hostname_info: PluginHostnameInfo,
|
pub hostname_info: PluginHostnameInfo,
|
||||||
pub row_actions: Vec<ActionId>,
|
pub remove_action: Option<ActionId>,
|
||||||
|
pub overflow_actions: Vec<ActionId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn export_url(
|
pub async fn export_url(
|
||||||
context: EffectContext,
|
context: EffectContext,
|
||||||
UrlPluginExportUrlParams {
|
UrlPluginExportUrlParams {
|
||||||
hostname_info,
|
hostname_info,
|
||||||
row_actions,
|
remove_action,
|
||||||
|
overflow_actions,
|
||||||
}: UrlPluginExportUrlParams,
|
}: UrlPluginExportUrlParams,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let context = context.deref()?;
|
let context = context.deref()?;
|
||||||
require_url_plugin(&context)?;
|
require_url_plugin(&context)?;
|
||||||
let plugin_id = context.seed.id.clone();
|
let plugin_id = context.seed.id.clone();
|
||||||
|
|
||||||
let entry = hostname_info.to_hostname_info(&plugin_id, row_actions);
|
let entry = hostname_info.to_hostname_info(&plugin_id, remove_action, overflow_actions);
|
||||||
|
|
||||||
context
|
context
|
||||||
.seed
|
.seed
|
||||||
.ctx
|
.ctx
|
||||||
.db
|
.db
|
||||||
.mutate(|db| {
|
.mutate(|db| {
|
||||||
let host = host_for(db, hostname_info.package_id.as_ref(), &hostname_info.host_id)?;
|
let host = host_for(
|
||||||
|
db,
|
||||||
|
hostname_info.package_id.as_ref(),
|
||||||
|
&hostname_info.host_id,
|
||||||
|
)?;
|
||||||
host.as_bindings_mut()
|
host.as_bindings_mut()
|
||||||
.as_idx_mut(&hostname_info.internal_port)
|
.as_idx_mut(&hostname_info.internal_port)
|
||||||
.or_not_found(t!("net.plugin.binding-not-found", binding = format!(
|
.or_not_found(t!(
|
||||||
"{}:{}:{}",
|
"net.plugin.binding-not-found",
|
||||||
hostname_info.package_id.as_deref().unwrap_or("STARTOS"),
|
binding = format!(
|
||||||
hostname_info.host_id,
|
"{}:{}:{}",
|
||||||
hostname_info.internal_port
|
hostname_info.package_id.as_deref().unwrap_or("STARTOS"),
|
||||||
)))?
|
hostname_info.host_id,
|
||||||
|
hostname_info.internal_port
|
||||||
|
)
|
||||||
|
))?
|
||||||
.as_addresses_mut()
|
.as_addresses_mut()
|
||||||
.as_available_mut()
|
.as_available_mut()
|
||||||
.mutate(|available: &mut BTreeSet<_>| {
|
.mutate(|available: &mut BTreeSet<_>| {
|
||||||
|
|||||||
@@ -159,7 +159,8 @@ export type Effects = {
|
|||||||
register(options: { tableAction: ActionId }): Promise<null>
|
register(options: { tableAction: ActionId }): Promise<null>
|
||||||
exportUrl(options: {
|
exportUrl(options: {
|
||||||
hostnameInfo: PluginHostnameInfo
|
hostnameInfo: PluginHostnameInfo
|
||||||
rowActions: ActionId[]
|
removeAction: ActionId | null
|
||||||
|
overflowActions: ActionId[]
|
||||||
}): Promise<null>
|
}): Promise<null>
|
||||||
clearUrls(options: { except: PluginHostnameInfo[] }): Promise<null>
|
clearUrls(options: { except: PluginHostnameInfo[] }): Promise<null>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export type HostnameMetadata =
|
|||||||
| {
|
| {
|
||||||
kind: 'plugin'
|
kind: 'plugin'
|
||||||
packageId: PackageId
|
packageId: PackageId
|
||||||
rowActions: Array<ActionId>
|
removeAction: ActionId | null
|
||||||
|
overflowActions: Array<ActionId>
|
||||||
info: unknown
|
info: unknown
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,6 @@ import type { PluginHostnameInfo } from './PluginHostnameInfo'
|
|||||||
|
|
||||||
export type UrlPluginExportUrlParams = {
|
export type UrlPluginExportUrlParams = {
|
||||||
hostnameInfo: PluginHostnameInfo
|
hostnameInfo: PluginHostnameInfo
|
||||||
rowActions: Array<ActionId>
|
removeAction: ActionId | null
|
||||||
|
overflowActions: Array<ActionId>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -765,7 +765,15 @@ export class StartSdk<Manifest extends T.SDKManifest> {
|
|||||||
effects: T.Effects,
|
effects: T.Effects,
|
||||||
options: {
|
options: {
|
||||||
hostnameInfo: T.PluginHostnameInfo
|
hostnameInfo: T.PluginHostnameInfo
|
||||||
rowActions: ActionInfo<
|
removeAction: ActionInfo<
|
||||||
|
T.ActionId,
|
||||||
|
{
|
||||||
|
urlPluginMetadata: T.PluginHostnameInfo & {
|
||||||
|
interfaceId: T.ServiceInterfaceId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> | null
|
||||||
|
overflowActions: ActionInfo<
|
||||||
T.ActionId,
|
T.ActionId,
|
||||||
{
|
{
|
||||||
urlPluginMetadata: T.PluginHostnameInfo & {
|
urlPluginMetadata: T.PluginHostnameInfo & {
|
||||||
@@ -777,7 +785,8 @@ export class StartSdk<Manifest extends T.SDKManifest> {
|
|||||||
) =>
|
) =>
|
||||||
effects.plugin.url.exportUrl({
|
effects.plugin.url.exportUrl({
|
||||||
hostnameInfo: options.hostnameInfo,
|
hostnameInfo: options.hostnameInfo,
|
||||||
rowActions: options.rowActions.map((a) => a.id),
|
removeAction: options.removeAction?.id ?? null,
|
||||||
|
overflowActions: options.overflowActions.map((a) => a.id),
|
||||||
}),
|
}),
|
||||||
setupExportedUrls, // similar to setupInterfaces
|
setupExportedUrls, // similar to setupInterfaces
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -5,11 +5,7 @@ import {
|
|||||||
input,
|
input,
|
||||||
signal,
|
signal,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import {
|
import { CopyService, DialogService, i18nPipe } from '@start9labs/shared'
|
||||||
CopyService,
|
|
||||||
DialogService,
|
|
||||||
i18nPipe,
|
|
||||||
} from '@start9labs/shared'
|
|
||||||
import { T } from '@start9labs/start-sdk'
|
import { T } from '@start9labs/start-sdk'
|
||||||
import { TUI_IS_MOBILE } from '@taiga-ui/cdk'
|
import { TUI_IS_MOBILE } from '@taiga-ui/cdk'
|
||||||
import {
|
import {
|
||||||
@@ -72,21 +68,30 @@ import {
|
|||||||
{{ 'Copy URL' | i18n }}
|
{{ 'Copy URL' | i18n }}
|
||||||
</button>
|
</button>
|
||||||
@if (address.hostnameInfo.metadata.kind === 'plugin') {
|
@if (address.hostnameInfo.metadata.kind === 'plugin') {
|
||||||
@for (
|
@if (address.hostnameInfo.metadata.removeAction) {
|
||||||
actionId of address.hostnameInfo.metadata.rowActions;
|
@if (
|
||||||
track actionId
|
pluginGroup().pluginActions[
|
||||||
) {
|
address.hostnameInfo.metadata.removeAction
|
||||||
@if (pluginGroup().pluginActions[actionId]; as meta) {
|
];
|
||||||
|
as meta
|
||||||
|
) {
|
||||||
<button
|
<button
|
||||||
tuiIconButton
|
tuiIconButton
|
||||||
appearance="flat-grayscale"
|
appearance="flat-grayscale"
|
||||||
iconStart="@tui.play"
|
iconStart="@tui.trash"
|
||||||
(click)="runRowAction(actionId, meta, address)"
|
(click)="
|
||||||
|
runRowAction(
|
||||||
|
address.hostnameInfo.metadata.removeAction,
|
||||||
|
meta,
|
||||||
|
address
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ meta.name }}
|
{{ meta.name }}
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<!-- TODO @MattHill: overflow -->
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="mobile">
|
<div class="mobile">
|
||||||
@@ -117,21 +122,30 @@ import {
|
|||||||
{{ 'Copy URL' | i18n }}
|
{{ 'Copy URL' | i18n }}
|
||||||
</button>
|
</button>
|
||||||
@if (address.hostnameInfo.metadata.kind === 'plugin') {
|
@if (address.hostnameInfo.metadata.kind === 'plugin') {
|
||||||
@for (
|
@if (address.hostnameInfo.metadata.removeAction) {
|
||||||
actionId of address.hostnameInfo.metadata.rowActions;
|
@if (
|
||||||
track actionId
|
pluginGroup().pluginActions[
|
||||||
) {
|
address.hostnameInfo.metadata.removeAction
|
||||||
@if (pluginGroup().pluginActions[actionId]; as meta) {
|
];
|
||||||
|
as meta
|
||||||
|
) {
|
||||||
<button
|
<button
|
||||||
tuiOption
|
tuiOption
|
||||||
new
|
new
|
||||||
iconStart="@tui.play"
|
iconStart="@tui.trash"
|
||||||
(click)="runRowAction(actionId, meta, address)"
|
(click)="
|
||||||
|
runRowAction(
|
||||||
|
address.hostnameInfo.metadata.removeAction,
|
||||||
|
meta,
|
||||||
|
address
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ meta.name }}
|
{{ meta.name }}
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<!-- TODO @MattHill: overflow -->
|
||||||
}
|
}
|
||||||
</tui-data-list>
|
</tui-data-list>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -94,16 +94,30 @@ export const mockPatchData: DataModel = {
|
|||||||
{
|
{
|
||||||
ssl: false,
|
ssl: false,
|
||||||
public: false,
|
public: false,
|
||||||
hostname: 'abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567abc.onion',
|
hostname:
|
||||||
|
'abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567abc.onion',
|
||||||
port: 80,
|
port: 80,
|
||||||
metadata: { kind: 'plugin', packageId: 'tor', rowActions: [], info: null },
|
metadata: {
|
||||||
|
kind: 'plugin',
|
||||||
|
packageId: 'tor',
|
||||||
|
removeAction: 'delete-onion-service',
|
||||||
|
overflowActions: [],
|
||||||
|
info: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ssl: true,
|
ssl: true,
|
||||||
public: false,
|
public: false,
|
||||||
hostname: 'abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567abc.onion',
|
hostname:
|
||||||
|
'abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567abc.onion',
|
||||||
port: 443,
|
port: 443,
|
||||||
metadata: { kind: 'plugin', packageId: 'tor', rowActions: [], info: null },
|
metadata: {
|
||||||
|
kind: 'plugin',
|
||||||
|
packageId: 'tor',
|
||||||
|
removeAction: 'delete-onion-service',
|
||||||
|
overflowActions: [],
|
||||||
|
info: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -595,16 +609,30 @@ export const mockPatchData: DataModel = {
|
|||||||
{
|
{
|
||||||
ssl: false,
|
ssl: false,
|
||||||
public: false,
|
public: false,
|
||||||
hostname: 'xyz789abc123def456ghi789jkl012mno345pqr678stu901vwx234.onion',
|
hostname:
|
||||||
|
'xyz789abc123def456ghi789jkl012mno345pqr678stu901vwx234.onion',
|
||||||
port: 42080,
|
port: 42080,
|
||||||
metadata: { kind: 'plugin', packageId: 'tor', rowActions: [], info: null },
|
metadata: {
|
||||||
|
kind: 'plugin',
|
||||||
|
packageId: 'tor',
|
||||||
|
removeAction: 'delete-onion-service',
|
||||||
|
overflowActions: [],
|
||||||
|
info: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ssl: true,
|
ssl: true,
|
||||||
public: false,
|
public: false,
|
||||||
hostname: 'xyz789abc123def456ghi789jkl012mno345pqr678stu901vwx234.onion',
|
hostname:
|
||||||
|
'xyz789abc123def456ghi789jkl012mno345pqr678stu901vwx234.onion',
|
||||||
port: 42443,
|
port: 42443,
|
||||||
metadata: { kind: 'plugin', packageId: 'tor', rowActions: [], info: null },
|
metadata: {
|
||||||
|
kind: 'plugin',
|
||||||
|
packageId: 'tor',
|
||||||
|
removeAction: 'delete-onion-service',
|
||||||
|
overflowActions: [],
|
||||||
|
info: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user