Skip to content

Commit

Permalink
fix(gui): Separate Landscape and Pro subscription sources (#684)
Browse files Browse the repository at this point in the history
We originally considered that having a Pro subscription managed via the
organization (represented by the existence of the Pro token inside the
Windows registry) should also mean that Landscape configuration data
should be treated as if coming from the same source, even in cases which
the organization didn't set any data about Landscape.

This PR changes that assumption by:
- Replacing the `GetSubscriptionInfo` RPC with `GetConfigSources`,
grouping both the Pro subscription and the Landscape config data
sources, so the GUI can decide which elements and features to present or
hide based on each source individually.
- Replacing the main app state from being the `SubscriptionInfo` to
being the `ConfigSources`, so we propagate that information letting the
individual pages decide which elements to display
- Changing the declaration of the `LandscapeConfigPage` route in the
Wizard to skip that page if the Landscape config source is the
organization
- Conditionally hiding or presenting the `Configure Landscape` button in
the SubscriptionStatus page variants, which still have their main layout
defined by the Pro subscription source, but now allowing that button to
show if the Landscape source allows configuration via the GUI. For
example, the Pro subscription may come from the organization and we
still present the `Configure Landscape` button if there is no Landscape
data or if the user provided it.
  • Loading branch information
CarlosNihelton authored Mar 12, 2024
2 parents d01e000 + d492c0f commit c4665ef
Show file tree
Hide file tree
Showing 30 changed files with 1,201 additions and 336 deletions.
17 changes: 15 additions & 2 deletions agentapi/agentapi.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ message Empty {}

service UI {
rpc ApplyProToken (ProAttachInfo) returns (SubscriptionInfo) {}
rpc ApplyLandscapeConfig(LandscapeConfig) returns (Empty) {}
rpc ApplyLandscapeConfig(LandscapeConfig) returns (LandscapeSource) {}
rpc Ping (Empty) returns (Empty) {}
rpc GetSubscriptionInfo(Empty) returns (SubscriptionInfo) {}
rpc GetConfigSources(Empty) returns (ConfigSources) {}
rpc NotifyPurchase(Empty) returns (SubscriptionInfo) {}
}

Expand All @@ -33,6 +33,19 @@ message SubscriptionInfo {
};
}

message LandscapeSource {
oneof landscapeSourceType {
Empty none = 1; // There is no active Landscape config data.
Empty user = 2; // The Landscape config is managed by the user, set via the GUI.
Empty organization = 3; // The Landscape config is managedby the sysadmin, set via the registry.
};
}

message ConfigSources {
SubscriptionInfo proSubscription = 1;
LandscapeSource landscapeSource = 2;
}

service WSLInstance {
rpc Connected (stream DistroInfo) returns (stream Port) {}
}
Expand Down
169 changes: 169 additions & 0 deletions agentapi/dart/lib/src/agentapi.pb.dart
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,175 @@ class SubscriptionInfo extends $pb.GeneratedMessage {
Empty ensureMicrosoftStore() => $_ensure(4);
}

enum LandscapeSource_LandscapeSourceType {
none,
user,
organization,
notSet
}

class LandscapeSource extends $pb.GeneratedMessage {
factory LandscapeSource({
Empty? none,
Empty? user,
Empty? organization,
}) {
final $result = create();
if (none != null) {
$result.none = none;
}
if (user != null) {
$result.user = user;
}
if (organization != null) {
$result.organization = organization;
}
return $result;
}
LandscapeSource._() : super();
factory LandscapeSource.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory LandscapeSource.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);

static const $core.Map<$core.int, LandscapeSource_LandscapeSourceType> _LandscapeSource_LandscapeSourceTypeByTag = {
1 : LandscapeSource_LandscapeSourceType.none,
2 : LandscapeSource_LandscapeSourceType.user,
3 : LandscapeSource_LandscapeSourceType.organization,
0 : LandscapeSource_LandscapeSourceType.notSet
};
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'LandscapeSource', package: const $pb.PackageName(_omitMessageNames ? '' : 'agentapi'), createEmptyInstance: create)
..oo(0, [1, 2, 3])
..aOM<Empty>(1, _omitFieldNames ? '' : 'none', subBuilder: Empty.create)
..aOM<Empty>(2, _omitFieldNames ? '' : 'user', subBuilder: Empty.create)
..aOM<Empty>(3, _omitFieldNames ? '' : 'organization', subBuilder: Empty.create)
..hasRequiredFields = false
;

@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
LandscapeSource clone() => LandscapeSource()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
LandscapeSource copyWith(void Function(LandscapeSource) updates) => super.copyWith((message) => updates(message as LandscapeSource)) as LandscapeSource;

$pb.BuilderInfo get info_ => _i;

@$core.pragma('dart2js:noInline')
static LandscapeSource create() => LandscapeSource._();
LandscapeSource createEmptyInstance() => create();
static $pb.PbList<LandscapeSource> createRepeated() => $pb.PbList<LandscapeSource>();
@$core.pragma('dart2js:noInline')
static LandscapeSource getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<LandscapeSource>(create);
static LandscapeSource? _defaultInstance;

LandscapeSource_LandscapeSourceType whichLandscapeSourceType() => _LandscapeSource_LandscapeSourceTypeByTag[$_whichOneof(0)]!;
void clearLandscapeSourceType() => clearField($_whichOneof(0));

@$pb.TagNumber(1)
Empty get none => $_getN(0);
@$pb.TagNumber(1)
set none(Empty v) { setField(1, v); }
@$pb.TagNumber(1)
$core.bool hasNone() => $_has(0);
@$pb.TagNumber(1)
void clearNone() => clearField(1);
@$pb.TagNumber(1)
Empty ensureNone() => $_ensure(0);

@$pb.TagNumber(2)
Empty get user => $_getN(1);
@$pb.TagNumber(2)
set user(Empty v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasUser() => $_has(1);
@$pb.TagNumber(2)
void clearUser() => clearField(2);
@$pb.TagNumber(2)
Empty ensureUser() => $_ensure(1);

@$pb.TagNumber(3)
Empty get organization => $_getN(2);
@$pb.TagNumber(3)
set organization(Empty v) { setField(3, v); }
@$pb.TagNumber(3)
$core.bool hasOrganization() => $_has(2);
@$pb.TagNumber(3)
void clearOrganization() => clearField(3);
@$pb.TagNumber(3)
Empty ensureOrganization() => $_ensure(2);
}

class ConfigSources extends $pb.GeneratedMessage {
factory ConfigSources({
SubscriptionInfo? proSubscription,
LandscapeSource? landscapeSource,
}) {
final $result = create();
if (proSubscription != null) {
$result.proSubscription = proSubscription;
}
if (landscapeSource != null) {
$result.landscapeSource = landscapeSource;
}
return $result;
}
ConfigSources._() : super();
factory ConfigSources.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory ConfigSources.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);

static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ConfigSources', package: const $pb.PackageName(_omitMessageNames ? '' : 'agentapi'), createEmptyInstance: create)
..aOM<SubscriptionInfo>(1, _omitFieldNames ? '' : 'proSubscription', protoName: 'proSubscription', subBuilder: SubscriptionInfo.create)
..aOM<LandscapeSource>(2, _omitFieldNames ? '' : 'landscapeSource', protoName: 'landscapeSource', subBuilder: LandscapeSource.create)
..hasRequiredFields = false
;

@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
ConfigSources clone() => ConfigSources()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
ConfigSources copyWith(void Function(ConfigSources) updates) => super.copyWith((message) => updates(message as ConfigSources)) as ConfigSources;

$pb.BuilderInfo get info_ => _i;

@$core.pragma('dart2js:noInline')
static ConfigSources create() => ConfigSources._();
ConfigSources createEmptyInstance() => create();
static $pb.PbList<ConfigSources> createRepeated() => $pb.PbList<ConfigSources>();
@$core.pragma('dart2js:noInline')
static ConfigSources getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ConfigSources>(create);
static ConfigSources? _defaultInstance;

@$pb.TagNumber(1)
SubscriptionInfo get proSubscription => $_getN(0);
@$pb.TagNumber(1)
set proSubscription(SubscriptionInfo v) { setField(1, v); }
@$pb.TagNumber(1)
$core.bool hasProSubscription() => $_has(0);
@$pb.TagNumber(1)
void clearProSubscription() => clearField(1);
@$pb.TagNumber(1)
SubscriptionInfo ensureProSubscription() => $_ensure(0);

@$pb.TagNumber(2)
LandscapeSource get landscapeSource => $_getN(1);
@$pb.TagNumber(2)
set landscapeSource(LandscapeSource v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasLandscapeSource() => $_has(1);
@$pb.TagNumber(2)
void clearLandscapeSource() => clearField(2);
@$pb.TagNumber(2)
LandscapeSource ensureLandscapeSource() => $_ensure(1);
}

class DistroInfo extends $pb.GeneratedMessage {
factory DistroInfo({
$core.String? wslName,
Expand Down
38 changes: 19 additions & 19 deletions agentapi/dart/lib/src/agentapi.pbgrpc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ class UIClient extends $grpc.Client {
'/agentapi.UI/ApplyProToken',
($0.ProAttachInfo value) => value.writeToBuffer(),
($core.List<$core.int> value) => $0.SubscriptionInfo.fromBuffer(value));
static final _$applyLandscapeConfig = $grpc.ClientMethod<$0.LandscapeConfig, $0.Empty>(
static final _$applyLandscapeConfig = $grpc.ClientMethod<$0.LandscapeConfig, $0.LandscapeSource>(
'/agentapi.UI/ApplyLandscapeConfig',
($0.LandscapeConfig value) => value.writeToBuffer(),
($core.List<$core.int> value) => $0.Empty.fromBuffer(value));
($core.List<$core.int> value) => $0.LandscapeSource.fromBuffer(value));
static final _$ping = $grpc.ClientMethod<$0.Empty, $0.Empty>(
'/agentapi.UI/Ping',
($0.Empty value) => value.writeToBuffer(),
($core.List<$core.int> value) => $0.Empty.fromBuffer(value));
static final _$getSubscriptionInfo = $grpc.ClientMethod<$0.Empty, $0.SubscriptionInfo>(
'/agentapi.UI/GetSubscriptionInfo',
static final _$getConfigSources = $grpc.ClientMethod<$0.Empty, $0.ConfigSources>(
'/agentapi.UI/GetConfigSources',
($0.Empty value) => value.writeToBuffer(),
($core.List<$core.int> value) => $0.SubscriptionInfo.fromBuffer(value));
($core.List<$core.int> value) => $0.ConfigSources.fromBuffer(value));
static final _$notifyPurchase = $grpc.ClientMethod<$0.Empty, $0.SubscriptionInfo>(
'/agentapi.UI/NotifyPurchase',
($0.Empty value) => value.writeToBuffer(),
Expand All @@ -52,16 +52,16 @@ class UIClient extends $grpc.Client {
return $createUnaryCall(_$applyProToken, request, options: options);
}

$grpc.ResponseFuture<$0.Empty> applyLandscapeConfig($0.LandscapeConfig request, {$grpc.CallOptions? options}) {
$grpc.ResponseFuture<$0.LandscapeSource> applyLandscapeConfig($0.LandscapeConfig request, {$grpc.CallOptions? options}) {
return $createUnaryCall(_$applyLandscapeConfig, request, options: options);
}

$grpc.ResponseFuture<$0.Empty> ping($0.Empty request, {$grpc.CallOptions? options}) {
return $createUnaryCall(_$ping, request, options: options);
}

$grpc.ResponseFuture<$0.SubscriptionInfo> getSubscriptionInfo($0.Empty request, {$grpc.CallOptions? options}) {
return $createUnaryCall(_$getSubscriptionInfo, request, options: options);
$grpc.ResponseFuture<$0.ConfigSources> getConfigSources($0.Empty request, {$grpc.CallOptions? options}) {
return $createUnaryCall(_$getConfigSources, request, options: options);
}

$grpc.ResponseFuture<$0.SubscriptionInfo> notifyPurchase($0.Empty request, {$grpc.CallOptions? options}) {
Expand All @@ -81,27 +81,27 @@ abstract class UIServiceBase extends $grpc.Service {
false,
($core.List<$core.int> value) => $0.ProAttachInfo.fromBuffer(value),
($0.SubscriptionInfo value) => value.writeToBuffer()));
$addMethod($grpc.ServiceMethod<$0.LandscapeConfig, $0.Empty>(
$addMethod($grpc.ServiceMethod<$0.LandscapeConfig, $0.LandscapeSource>(
'ApplyLandscapeConfig',
applyLandscapeConfig_Pre,
false,
false,
($core.List<$core.int> value) => $0.LandscapeConfig.fromBuffer(value),
($0.Empty value) => value.writeToBuffer()));
($0.LandscapeSource value) => value.writeToBuffer()));
$addMethod($grpc.ServiceMethod<$0.Empty, $0.Empty>(
'Ping',
ping_Pre,
false,
false,
($core.List<$core.int> value) => $0.Empty.fromBuffer(value),
($0.Empty value) => value.writeToBuffer()));
$addMethod($grpc.ServiceMethod<$0.Empty, $0.SubscriptionInfo>(
'GetSubscriptionInfo',
getSubscriptionInfo_Pre,
$addMethod($grpc.ServiceMethod<$0.Empty, $0.ConfigSources>(
'GetConfigSources',
getConfigSources_Pre,
false,
false,
($core.List<$core.int> value) => $0.Empty.fromBuffer(value),
($0.SubscriptionInfo value) => value.writeToBuffer()));
($0.ConfigSources value) => value.writeToBuffer()));
$addMethod($grpc.ServiceMethod<$0.Empty, $0.SubscriptionInfo>(
'NotifyPurchase',
notifyPurchase_Pre,
Expand All @@ -115,26 +115,26 @@ abstract class UIServiceBase extends $grpc.Service {
return applyProToken(call, await request);
}

$async.Future<$0.Empty> applyLandscapeConfig_Pre($grpc.ServiceCall call, $async.Future<$0.LandscapeConfig> request) async {
$async.Future<$0.LandscapeSource> applyLandscapeConfig_Pre($grpc.ServiceCall call, $async.Future<$0.LandscapeConfig> request) async {
return applyLandscapeConfig(call, await request);
}

$async.Future<$0.Empty> ping_Pre($grpc.ServiceCall call, $async.Future<$0.Empty> request) async {
return ping(call, await request);
}

$async.Future<$0.SubscriptionInfo> getSubscriptionInfo_Pre($grpc.ServiceCall call, $async.Future<$0.Empty> request) async {
return getSubscriptionInfo(call, await request);
$async.Future<$0.ConfigSources> getConfigSources_Pre($grpc.ServiceCall call, $async.Future<$0.Empty> request) async {
return getConfigSources(call, await request);
}

$async.Future<$0.SubscriptionInfo> notifyPurchase_Pre($grpc.ServiceCall call, $async.Future<$0.Empty> request) async {
return notifyPurchase(call, await request);
}

$async.Future<$0.SubscriptionInfo> applyProToken($grpc.ServiceCall call, $0.ProAttachInfo request);
$async.Future<$0.Empty> applyLandscapeConfig($grpc.ServiceCall call, $0.LandscapeConfig request);
$async.Future<$0.LandscapeSource> applyLandscapeConfig($grpc.ServiceCall call, $0.LandscapeConfig request);
$async.Future<$0.Empty> ping($grpc.ServiceCall call, $0.Empty request);
$async.Future<$0.SubscriptionInfo> getSubscriptionInfo($grpc.ServiceCall call, $0.Empty request);
$async.Future<$0.ConfigSources> getConfigSources($grpc.ServiceCall call, $0.Empty request);
$async.Future<$0.SubscriptionInfo> notifyPurchase($grpc.ServiceCall call, $0.Empty request);
}
@$pb.GrpcServiceName('agentapi.WSLInstance')
Expand Down
35 changes: 35 additions & 0 deletions agentapi/dart/lib/src/agentapi.pbjson.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,41 @@ final $typed_data.Uint8List subscriptionInfoDescriptor = $convert.base64Decode(
'BSDG9yZ2FuaXphdGlvbhI5Cg5taWNyb3NvZnRTdG9yZRgFIAEoCzIPLmFnZW50YXBpLkVtcHR5'
'SABSDm1pY3Jvc29mdFN0b3JlQhIKEHN1YnNjcmlwdGlvblR5cGU=');

@$core.Deprecated('Use landscapeSourceDescriptor instead')
const LandscapeSource$json = {
'1': 'LandscapeSource',
'2': [
{'1': 'none', '3': 1, '4': 1, '5': 11, '6': '.agentapi.Empty', '9': 0, '10': 'none'},
{'1': 'user', '3': 2, '4': 1, '5': 11, '6': '.agentapi.Empty', '9': 0, '10': 'user'},
{'1': 'organization', '3': 3, '4': 1, '5': 11, '6': '.agentapi.Empty', '9': 0, '10': 'organization'},
],
'8': [
{'1': 'landscapeSourceType'},
],
};

/// Descriptor for `LandscapeSource`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List landscapeSourceDescriptor = $convert.base64Decode(
'Cg9MYW5kc2NhcGVTb3VyY2USJQoEbm9uZRgBIAEoCzIPLmFnZW50YXBpLkVtcHR5SABSBG5vbm'
'USJQoEdXNlchgCIAEoCzIPLmFnZW50YXBpLkVtcHR5SABSBHVzZXISNQoMb3JnYW5pemF0aW9u'
'GAMgASgLMg8uYWdlbnRhcGkuRW1wdHlIAFIMb3JnYW5pemF0aW9uQhUKE2xhbmRzY2FwZVNvdX'
'JjZVR5cGU=');

@$core.Deprecated('Use configSourcesDescriptor instead')
const ConfigSources$json = {
'1': 'ConfigSources',
'2': [
{'1': 'proSubscription', '3': 1, '4': 1, '5': 11, '6': '.agentapi.SubscriptionInfo', '10': 'proSubscription'},
{'1': 'landscapeSource', '3': 2, '4': 1, '5': 11, '6': '.agentapi.LandscapeSource', '10': 'landscapeSource'},
],
};

/// Descriptor for `ConfigSources`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List configSourcesDescriptor = $convert.base64Decode(
'Cg1Db25maWdTb3VyY2VzEkQKD3Byb1N1YnNjcmlwdGlvbhgBIAEoCzIaLmFnZW50YXBpLlN1Yn'
'NjcmlwdGlvbkluZm9SD3Byb1N1YnNjcmlwdGlvbhJDCg9sYW5kc2NhcGVTb3VyY2UYAiABKAsy'
'GS5hZ2VudGFwaS5MYW5kc2NhcGVTb3VyY2VSD2xhbmRzY2FwZVNvdXJjZQ==');

@$core.Deprecated('Use distroInfoDescriptor instead')
const DistroInfo$json = {
'1': 'DistroInfo',
Expand Down
Loading

0 comments on commit c4665ef

Please sign in to comment.