Skip to content

Commit 674c671

Browse files
feat(frontend): edit ufo metadata (#2777)
* feat(frontend): edit ufo metadata * chore: lint
1 parent 3c951c5 commit 674c671

10 files changed

Lines changed: 270 additions & 83 deletions

File tree

src/frontend/src/lib/api/mission-control.api.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,21 @@ export const setSatelliteMetadata = async ({
140140
return set_satellite_metadata(satelliteId, metadata);
141141
};
142142

143+
export const setUfoMetadata = async ({
144+
missionControlId,
145+
ufoId,
146+
metadata,
147+
identity
148+
}: {
149+
missionControlId: MissionControlId;
150+
ufoId: UfoId;
151+
metadata: Metadata;
152+
identity: NullishIdentity;
153+
}): Promise<MissionControlDid.Ufo> => {
154+
const { set_ufo_metadata } = await getMissionControlActor({ missionControlId, identity });
155+
return set_ufo_metadata(ufoId, metadata);
156+
};
157+
143158
export const setOrbitersController = async ({
144159
missionControlId,
145160
orbiterIds,

src/frontend/src/lib/components/satellites/overview/SatelliteEditDetails.svelte renamed to src/frontend/src/lib/components/modules/segments/SegmentWithMetadataEditDetails.svelte

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,63 +6,63 @@
66
import { isBusy } from '$lib/derived/app/busy.derived';
77
import { authIdentity } from '$lib/derived/auth.derived';
88
import { missionControlId } from '$lib/derived/console/account.mission-control.derived';
9-
import { setSatelliteMetadata } from '$lib/services/metadata.services';
9+
import type { SetMetadataParams, SetMetadataResult } from '$lib/services/metadata.services';
1010
import { busy } from '$lib/stores/app/busy.store';
1111
import { i18n } from '$lib/stores/app/i18n.store';
1212
import { toasts } from '$lib/stores/app/toasts.store';
1313
import type { MetadataUiTags } from '$lib/types/metadata';
14-
import type { Satellite } from '$lib/types/satellite';
14+
import type { SegmentWithMetadata } from '$lib/types/segment';
1515
import {
1616
metadataUiEnvironment,
1717
metadataUiName,
1818
metadataUiTags
1919
} from '$lib/utils/metadata-ui.utils';
2020
2121
interface Props {
22-
satellite: Satellite;
22+
segment: SegmentWithMetadata;
23+
updateMetadata: (params: SetMetadataParams) => Promise<SetMetadataResult>;
2324
}
2425
25-
let { satellite }: Props = $props();
26+
let { segment, updateMetadata }: Props = $props();
2627
2728
// svelte-ignore state_referenced_locally
28-
let satName = $state(metadataUiName(satellite));
29+
let segmentName = $state(metadataUiName(segment));
2930
// svelte-ignore state_referenced_locally
30-
let satEnv = $state<string | undefined>(metadataUiEnvironment(satellite));
31+
let segmentEnv = $state<string | undefined>(metadataUiEnvironment(segment));
3132
3233
// svelte-ignore state_referenced_locally
33-
let satTagsInput = $state(metadataUiTags(satellite)?.join(',') ?? '');
34-
let satTags = $derived<MetadataUiTags>(
35-
satTagsInput
34+
let segmentTagsInput = $state(metadataUiTags(segment)?.join(',') ?? '');
35+
let segmentTags = $derived<MetadataUiTags>(
36+
segmentTagsInput
3637
.split(/[\n,]+/)
3738
.map((input) => input.toLowerCase().trim())
3839
.filter(notEmptyString)
3940
);
4041
41-
let visible: boolean = $state(false);
42+
let visible = $state(false);
4243
43-
let validConfirm = $derived(nonNullish(satName) && satName !== '');
44+
let validConfirm = $derived(nonNullish(segmentName) && segmentName !== '');
4445
4546
const handleSubmit = async ($event: SubmitEvent) => {
4647
$event.preventDefault();
4748
4849
if (!validConfirm) {
4950
// Submit is disabled if not valid
5051
toasts.error({
51-
text: $i18n.errors.satellite_name_missing
52+
text: $i18n.errors.segment_name_missing
5253
});
5354
return;
5455
}
5556
5657
busy.start();
5758
58-
const { success } = await setSatelliteMetadata({
59+
const { success } = await updateMetadata({
5960
missionControlId: $missionControlId,
6061
identity: $authIdentity,
61-
satellite,
6262
metadata: {
63-
name: satName,
64-
environment: satEnv,
65-
tags: satTags
63+
name: segmentName,
64+
environment: segmentEnv,
65+
tags: segmentTags
6666
}
6767
});
6868
@@ -80,46 +80,46 @@
8080
};
8181
</script>
8282

83-
<button class="menu" onclick={open}><IconEdit /> {$i18n.satellites.edit_details}</button>
83+
<button class="menu" onclick={open}><IconEdit /> {$i18n.core.edit_details}</button>
8484

8585
<Popover backdrop="dark" center bind:visible>
8686
<form class="container" onsubmit={handleSubmit}>
87-
<Value ref="satelliteName">
87+
<Value ref="segmentName">
8888
{#snippet label()}
89-
{$i18n.satellites.satellite_name}
89+
{$i18n.core.name}
9090
{/snippet}
9191

9292
<input
93-
id="satelliteName"
93+
id="segmentName"
9494
autocomplete="off"
9595
data-1p-ignore
9696
disabled={$isBusy}
9797
maxlength={64}
98-
placeholder={$i18n.satellites.edit_details}
98+
placeholder={$i18n.core.edit_details}
9999
type="text"
100-
bind:value={satName}
100+
bind:value={segmentName}
101101
/>
102102
</Value>
103103

104-
<Value ref="satelliteEnv">
104+
<Value ref="segmentEnv">
105105
{#snippet label()}
106106
{$i18n.core.environment}
107107
{/snippet}
108108

109-
<select id="satelliteEnv" disabled={$isBusy} bind:value={satEnv}>
109+
<select id="segmentEnv" disabled={$isBusy} bind:value={segmentEnv}>
110110
<option value={undefined}>{$i18n.core.unspecified}</option>
111111
<option value="production"> {$i18n.core.production} </option>
112112
<option value="staging"> {$i18n.core.staging} </option>
113113
<option value="test"> {$i18n.core.test} </option>
114114
</select>
115115
</Value>
116116

117-
<Value ref="satelliteTags">
117+
<Value ref="segmentTags">
118118
{#snippet label()}
119119
{$i18n.core.tags}
120120
{/snippet}
121121

122-
<textarea placeholder={$i18n.core.tags_placeholder} rows="5" bind:value={satTagsInput}
122+
<textarea placeholder={$i18n.core.tags_placeholder} rows="5" bind:value={segmentTagsInput}
123123
></textarea>
124124
</Value>
125125

src/frontend/src/lib/components/satellites/overview/SatelliteOverviewActions.svelte

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
<script lang="ts">
22
import DetachSegment from '$lib/components/modules/attach-detach/DetachSegment.svelte';
33
import SegmentActions from '$lib/components/modules/segments/SegmentActions.svelte';
4-
import SatelliteEditDetails from '$lib/components/satellites/overview/SatelliteEditDetails.svelte';
4+
import SegmentWithMetadataEditDetails from '$lib/components/modules/segments/SegmentWithMetadataEditDetails.svelte';
55
import SatelliteReloadVersion from '$lib/components/satellites/overview/SatelliteReloadVersion.svelte';
66
import SatelliteVisit from '$lib/components/satellites/overview/SatelliteVisit.svelte';
7+
import {
8+
type SetMetadataParams,
9+
type SetMetadataResult,
10+
setSatelliteMetadata
11+
} from '$lib/services/metadata.services';
712
import type { Satellite } from '$lib/types/satellite';
813
914
interface Props {
@@ -15,6 +20,12 @@
1520
1621
let visible: boolean = $state(false);
1722
const close = () => (visible = false);
23+
24+
const updateMetadata = (params: SetMetadataParams): Promise<SetMetadataResult> =>
25+
setSatelliteMetadata({
26+
...params,
27+
satellite
28+
});
1829
</script>
1930

2031
<SegmentActions bind:visible>
@@ -23,7 +34,7 @@
2334
{/snippet}
2435

2536
{#snippet moreActions()}
26-
<SatelliteEditDetails {satellite} />
37+
<SegmentWithMetadataEditDetails segment={satellite} {updateMetadata} />
2738

2839
<DetachSegment
2940
{monitoringEnabled}

src/frontend/src/lib/components/ufos/overview/UfoOverview.svelte

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import SegmentWithMetadataEnvironmentText from '$lib/components/modules/segments/SegmentWithMetadataEnvironmentText.svelte';
77
import SegmentWithMetadataName from '$lib/components/modules/segments/SegmentWithMetadataName.svelte';
88
import SegmentWithMetadataTags from '$lib/components/modules/segments/SegmentWithMetadataTags.svelte';
9+
import UfoOverviewActions from '$lib/components/ufos/overview/UfoOverviewActions.svelte';
910
import Identifier from '$lib/components/ui/Identifier.svelte';
1011
import Value from '$lib/components/ui/Value.svelte';
1112
import { i18n } from '$lib/stores/app/i18n.store';
@@ -33,35 +34,33 @@
3334

3435
<CanisterSyncData canisterId={ufo.ufo_id} bind:canister />
3536

36-
<div class="overview">
37-
<div class="card-container with-title">
38-
<span class="title">{$i18n.satellites.overview}</span>
37+
<div class="card-container with-title">
38+
<span class="title">{$i18n.satellites.overview}</span>
3939

40-
<div class="columns-3 fit-column-1">
41-
<div class="id">
42-
<SegmentWithMetadataName segment={ufo} />
40+
<div class="columns-3 fit-column-1">
41+
<div class="id">
42+
<SegmentWithMetadataName segment={ufo} />
4343

44-
<SegmentWithMetadataEnvironmentText segment={ufo} />
44+
<SegmentWithMetadataEnvironmentText segment={ufo} />
4545

46-
<SegmentWithMetadataTags segment={ufo} />
47-
</div>
46+
<SegmentWithMetadataTags segment={ufo} />
47+
</div>
4848

49-
<div>
50-
<Value>
51-
{#snippet label()}
52-
{$i18n.ufo.id}
53-
{/snippet}
54-
<Identifier identifier={ufoId} shorten={false} small={false} />
55-
</Value>
49+
<div>
50+
<Value>
51+
{#snippet label()}
52+
{$i18n.ufo.id}
53+
{/snippet}
54+
<Identifier identifier={ufoId} shorten={false} small={false} />
55+
</Value>
5656

57-
<CanisterSubnet canisterId={ufo.ufo_id} />
58-
</div>
57+
<CanisterSubnet canisterId={ufo.ufo_id} />
5958
</div>
6059
</div>
61-
62-
<div class="actions">TODO</div>
6360
</div>
6461

62+
<UfoOverviewActions {monitoringEnabled} {ufo} />
63+
6564
<div class="card-container with-title">
6665
<span class="title">{$i18n.monitoring.runtime}</span>
6766

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<script lang="ts">
2+
import SegmentActions from '$lib/components/modules/segments/SegmentActions.svelte';
3+
import SegmentWithMetadataEditDetails from '$lib/components/modules/segments/SegmentWithMetadataEditDetails.svelte';
4+
import {
5+
type SetMetadataParams,
6+
type SetMetadataResult,
7+
setUfoMetadata
8+
} from '$lib/services/metadata.services';
9+
import type { Ufo } from '$lib/types/ufo';
10+
11+
interface Props {
12+
ufo: Ufo;
13+
monitoringEnabled: boolean;
14+
}
15+
16+
let { ufo, monitoringEnabled }: Props = $props();
17+
18+
let visible: boolean = $state(false);
19+
const close = () => (visible = false);
20+
21+
const updateMetadata = (params: SetMetadataParams): Promise<SetMetadataResult> =>
22+
setUfoMetadata({
23+
...params,
24+
ufo
25+
});
26+
</script>
27+
28+
<SegmentActions bind:visible>
29+
{#snippet moreActions()}
30+
<SegmentWithMetadataEditDetails segment={ufo} {updateMetadata} />
31+
{/snippet}
32+
</SegmentActions>

src/frontend/src/lib/i18n/en.json

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@
124124
"lets_go": "Let's go!",
125125
"name": "Name",
126126
"environment": "Environment",
127-
"tags": "Tags"
127+
"tags": "Tags",
128+
"edit_details": "Edit details",
129+
"tags_placeholder": "Comma-separated or one per line. Leave empty for no tags."
128130
},
129131
"canisters": {
130132
"top_up": "Top-up",
@@ -336,9 +338,7 @@
336338
"application": "Application",
337339
"application_description": "Data storage, user management, serverless functions",
338340
"application_hint": "Your satellite will be initialized with settings optimized for an application.",
339-
"tags_placeholder": "Comma-separated or one per line. Leave empty for no tags.",
340341
"enter_name": "Enter a name for your Satellite",
341-
"edit_details": "Edit details",
342342
"create_satellite_price": "Starting a new Satellite requires {0}.",
343343
"loading_satellites": "Loading your Satellites",
344344
"overview": "Overview",
@@ -369,7 +369,8 @@
369369
"ready": "Your Mission Control is ready!",
370370
"attaching": "Sharing existing modules with Mission Control...",
371371
"warn_attaching": "Failed to share the following modules with Mission Control:",
372-
"warn_satellite_metadata_update": "Satellite not found in Mission Control. This is unexpected."
372+
"warn_satellite_metadata_update": "Satellite not found in Mission Control. This is unexpected.",
373+
"warn_ufo_metadata_update": "UFO not found in Mission Control. This is unexpected."
373374
},
374375
"wallet": {
375376
"title": "Wallet",
@@ -617,13 +618,14 @@
617618
"cli_missing_params": "Missing URL parameters. Either the redirection URL or principal is not provided.",
618619
"cli_missing_selection": "No Mission Control or Satellite(s) selected.",
619620
"cli_unexpected_error": "Unexpected error(s) while adding your admin access key.",
620-
"satellite_name_missing": "A name for the Satellite must be provided.",
621+
"segment_name_missing": "A name must be provided.",
621622
"satellite_kind": "Please choose what you are building to continue.",
622623
"satellite_unexpected_error": "Unexpected error(s) while creating the Satellite.",
623624
"satellite_no_found": "Nothing here. Return to your launchpad to find your Satellites.",
624625
"satellite_metadata_update": "Unexpected error(s) while trying to set the metadata of your Satellite.",
625626
"satellite_missing_name": "A name must be provided.",
626627
"satellites_not_loaded": "The Satellites data are not yet loaded.",
628+
"ufo_metadata_update": "Unexpected error(s) while trying to set the metadata of your UFO.",
627629
"create_ufo_name_missing": "A name for the UFO must be provided.",
628630
"create_ufo_unexpected_error": "Unexpected error(s) while creating the UFO.",
629631
"ufo_not_found": "Nothing here. Return to your launchpad to find your UFOs.",
@@ -712,6 +714,7 @@
712714
"invalid_email": "Please enter a valid email address.",
713715
"invalid_destination": "Please enter a valid destination address.",
714716
"invalid_metadata": "The metadata provided is invalid.",
717+
"update_metadata_error": "Unexpected error(s) while updating the metadata in the Console.",
715718
"empty_amount": "Please enter an amount for the transfer.",
716719
"cycles_transfer_not_supported": "Transferring cycles from Mission Control is not yet supported. Get in touch!",
717720
"convert_icp_to_cycles_not_supported": "Converting ICP to Cycles with the Mission Control is not yet supported. Get in touch!",

0 commit comments

Comments
 (0)