mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +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
|
||||
./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
|
||||
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
|
||||
|
||||
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 {
|
||||
package_id: PackageId,
|
||||
row_actions: Vec<ActionId>,
|
||||
remove_action: Option<ActionId>,
|
||||
overflow_actions: Vec<ActionId>,
|
||||
#[ts(type = "unknown")]
|
||||
#[serde(default)]
|
||||
info: Value,
|
||||
@@ -99,7 +100,8 @@ impl PluginHostnameInfo {
|
||||
pub fn to_hostname_info(
|
||||
&self,
|
||||
plugin_package: &PackageId,
|
||||
row_actions: Vec<ActionId>,
|
||||
remove_action: Option<ActionId>,
|
||||
overflow_actions: Vec<ActionId>,
|
||||
) -> HostnameInfo {
|
||||
HostnameInfo {
|
||||
ssl: self.ssl,
|
||||
@@ -109,7 +111,8 @@ impl PluginHostnameInfo {
|
||||
metadata: HostnameMetadata::Plugin {
|
||||
package_id: plugin_package.clone(),
|
||||
info: self.info.clone(),
|
||||
row_actions,
|
||||
remove_action,
|
||||
overflow_actions,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -118,7 +121,9 @@ impl PluginHostnameInfo {
|
||||
/// (comparing address fields only, not row_actions).
|
||||
pub fn matches_hostname_info(&self, h: &HostnameInfo, plugin_package: &PackageId) -> bool {
|
||||
match &h.metadata {
|
||||
HostnameMetadata::Plugin { package_id, info, .. } => {
|
||||
HostnameMetadata::Plugin {
|
||||
package_id, info, ..
|
||||
} => {
|
||||
package_id == plugin_package
|
||||
&& h.ssl == self.ssl
|
||||
&& h.public == self.public
|
||||
|
||||
@@ -19,7 +19,10 @@ fn require_url_plugin(context: &Arc<Service>) -> Result<(), Error> {
|
||||
.contains(&PluginId::UrlV0)
|
||||
{
|
||||
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,
|
||||
));
|
||||
}
|
||||
@@ -68,36 +71,45 @@ pub async fn register(
|
||||
#[ts(export)]
|
||||
pub struct UrlPluginExportUrlParams {
|
||||
pub hostname_info: PluginHostnameInfo,
|
||||
pub row_actions: Vec<ActionId>,
|
||||
pub remove_action: Option<ActionId>,
|
||||
pub overflow_actions: Vec<ActionId>,
|
||||
}
|
||||
|
||||
pub async fn export_url(
|
||||
context: EffectContext,
|
||||
UrlPluginExportUrlParams {
|
||||
hostname_info,
|
||||
row_actions,
|
||||
remove_action,
|
||||
overflow_actions,
|
||||
}: UrlPluginExportUrlParams,
|
||||
) -> Result<(), Error> {
|
||||
let context = context.deref()?;
|
||||
require_url_plugin(&context)?;
|
||||
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
|
||||
.seed
|
||||
.ctx
|
||||
.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()
|
||||
.as_idx_mut(&hostname_info.internal_port)
|
||||
.or_not_found(t!("net.plugin.binding-not-found", binding = format!(
|
||||
"{}:{}:{}",
|
||||
hostname_info.package_id.as_deref().unwrap_or("STARTOS"),
|
||||
hostname_info.host_id,
|
||||
hostname_info.internal_port
|
||||
)))?
|
||||
.or_not_found(t!(
|
||||
"net.plugin.binding-not-found",
|
||||
binding = format!(
|
||||
"{}:{}:{}",
|
||||
hostname_info.package_id.as_deref().unwrap_or("STARTOS"),
|
||||
hostname_info.host_id,
|
||||
hostname_info.internal_port
|
||||
)
|
||||
))?
|
||||
.as_addresses_mut()
|
||||
.as_available_mut()
|
||||
.mutate(|available: &mut BTreeSet<_>| {
|
||||
|
||||
@@ -159,7 +159,8 @@ export type Effects = {
|
||||
register(options: { tableAction: ActionId }): Promise<null>
|
||||
exportUrl(options: {
|
||||
hostnameInfo: PluginHostnameInfo
|
||||
rowActions: ActionId[]
|
||||
removeAction: ActionId | null
|
||||
overflowActions: ActionId[]
|
||||
}): Promise<null>
|
||||
clearUrls(options: { except: PluginHostnameInfo[] }): Promise<null>
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ export type HostnameMetadata =
|
||||
| {
|
||||
kind: 'plugin'
|
||||
packageId: PackageId
|
||||
rowActions: Array<ActionId>
|
||||
removeAction: ActionId | null
|
||||
overflowActions: Array<ActionId>
|
||||
info: unknown
|
||||
}
|
||||
|
||||
@@ -4,5 +4,6 @@ import type { PluginHostnameInfo } from './PluginHostnameInfo'
|
||||
|
||||
export type UrlPluginExportUrlParams = {
|
||||
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,
|
||||
options: {
|
||||
hostnameInfo: T.PluginHostnameInfo
|
||||
rowActions: ActionInfo<
|
||||
removeAction: ActionInfo<
|
||||
T.ActionId,
|
||||
{
|
||||
urlPluginMetadata: T.PluginHostnameInfo & {
|
||||
interfaceId: T.ServiceInterfaceId
|
||||
}
|
||||
}
|
||||
> | null
|
||||
overflowActions: ActionInfo<
|
||||
T.ActionId,
|
||||
{
|
||||
urlPluginMetadata: T.PluginHostnameInfo & {
|
||||
@@ -777,7 +785,8 @@ export class StartSdk<Manifest extends T.SDKManifest> {
|
||||
) =>
|
||||
effects.plugin.url.exportUrl({
|
||||
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
|
||||
}),
|
||||
|
||||
@@ -5,11 +5,7 @@ import {
|
||||
input,
|
||||
signal,
|
||||
} from '@angular/core'
|
||||
import {
|
||||
CopyService,
|
||||
DialogService,
|
||||
i18nPipe,
|
||||
} from '@start9labs/shared'
|
||||
import { CopyService, DialogService, i18nPipe } from '@start9labs/shared'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { TUI_IS_MOBILE } from '@taiga-ui/cdk'
|
||||
import {
|
||||
@@ -72,21 +68,30 @@ import {
|
||||
{{ 'Copy URL' | i18n }}
|
||||
</button>
|
||||
@if (address.hostnameInfo.metadata.kind === 'plugin') {
|
||||
@for (
|
||||
actionId of address.hostnameInfo.metadata.rowActions;
|
||||
track actionId
|
||||
) {
|
||||
@if (pluginGroup().pluginActions[actionId]; as meta) {
|
||||
@if (address.hostnameInfo.metadata.removeAction) {
|
||||
@if (
|
||||
pluginGroup().pluginActions[
|
||||
address.hostnameInfo.metadata.removeAction
|
||||
];
|
||||
as meta
|
||||
) {
|
||||
<button
|
||||
tuiIconButton
|
||||
appearance="flat-grayscale"
|
||||
iconStart="@tui.play"
|
||||
(click)="runRowAction(actionId, meta, address)"
|
||||
iconStart="@tui.trash"
|
||||
(click)="
|
||||
runRowAction(
|
||||
address.hostnameInfo.metadata.removeAction,
|
||||
meta,
|
||||
address
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ meta.name }}
|
||||
</button>
|
||||
}
|
||||
}
|
||||
<!-- TODO @MattHill: overflow -->
|
||||
}
|
||||
</div>
|
||||
<div class="mobile">
|
||||
@@ -117,21 +122,30 @@ import {
|
||||
{{ 'Copy URL' | i18n }}
|
||||
</button>
|
||||
@if (address.hostnameInfo.metadata.kind === 'plugin') {
|
||||
@for (
|
||||
actionId of address.hostnameInfo.metadata.rowActions;
|
||||
track actionId
|
||||
) {
|
||||
@if (pluginGroup().pluginActions[actionId]; as meta) {
|
||||
@if (address.hostnameInfo.metadata.removeAction) {
|
||||
@if (
|
||||
pluginGroup().pluginActions[
|
||||
address.hostnameInfo.metadata.removeAction
|
||||
];
|
||||
as meta
|
||||
) {
|
||||
<button
|
||||
tuiOption
|
||||
new
|
||||
iconStart="@tui.play"
|
||||
(click)="runRowAction(actionId, meta, address)"
|
||||
iconStart="@tui.trash"
|
||||
(click)="
|
||||
runRowAction(
|
||||
address.hostnameInfo.metadata.removeAction,
|
||||
meta,
|
||||
address
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ meta.name }}
|
||||
</button>
|
||||
}
|
||||
}
|
||||
<!-- TODO @MattHill: overflow -->
|
||||
}
|
||||
</tui-data-list>
|
||||
</button>
|
||||
|
||||
@@ -94,16 +94,30 @@ export const mockPatchData: DataModel = {
|
||||
{
|
||||
ssl: false,
|
||||
public: false,
|
||||
hostname: 'abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567abc.onion',
|
||||
hostname:
|
||||
'abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567abc.onion',
|
||||
port: 80,
|
||||
metadata: { kind: 'plugin', packageId: 'tor', rowActions: [], info: null },
|
||||
metadata: {
|
||||
kind: 'plugin',
|
||||
packageId: 'tor',
|
||||
removeAction: 'delete-onion-service',
|
||||
overflowActions: [],
|
||||
info: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
ssl: true,
|
||||
public: false,
|
||||
hostname: 'abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567abc.onion',
|
||||
hostname:
|
||||
'abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567abc.onion',
|
||||
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,
|
||||
public: false,
|
||||
hostname: 'xyz789abc123def456ghi789jkl012mno345pqr678stu901vwx234.onion',
|
||||
hostname:
|
||||
'xyz789abc123def456ghi789jkl012mno345pqr678stu901vwx234.onion',
|
||||
port: 42080,
|
||||
metadata: { kind: 'plugin', packageId: 'tor', rowActions: [], info: null },
|
||||
metadata: {
|
||||
kind: 'plugin',
|
||||
packageId: 'tor',
|
||||
removeAction: 'delete-onion-service',
|
||||
overflowActions: [],
|
||||
info: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
ssl: true,
|
||||
public: false,
|
||||
hostname: 'xyz789abc123def456ghi789jkl012mno345pqr678stu901vwx234.onion',
|
||||
hostname:
|
||||
'xyz789abc123def456ghi789jkl012mno345pqr678stu901vwx234.onion',
|
||||
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