Skip to content

Commit f8f110d

Browse files
feat: restyle app card (#337)
* feat: extend app and environment types for better querying * feat: get members and environments when querying apps * feat: rework app card design, show member, env and integration providers * fix: better responsive grid * fix: remove unused fields from query * fix: tweak typography * chore: regenerate types * fix: iterator keys * feat: restyle encryption mode indicator * feat: add encryption mode indicator to app card
1 parent 4f3c1b9 commit f8f110d

File tree

10 files changed

+318
-208
lines changed

10 files changed

+318
-208
lines changed

backend/backend/graphene/types.py

+65-57
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,66 @@ class Meta:
176176
)
177177

178178

179+
class ProviderType(graphene.ObjectType):
180+
id = graphene.String(required=True)
181+
name = graphene.String(required=True)
182+
expected_credentials = graphene.List(
183+
graphene.NonNull(graphene.String), required=True
184+
)
185+
optional_credentials = graphene.List(
186+
graphene.NonNull(graphene.String), required=True
187+
)
188+
auth_scheme = graphene.String()
189+
190+
191+
class ServiceType(ObjectType):
192+
id = graphene.String()
193+
name = graphene.String()
194+
resource_type = graphene.String()
195+
provider = graphene.Field(ProviderType)
196+
197+
198+
class EnvironmentSyncEventType(DjangoObjectType):
199+
class Meta:
200+
model = EnvironmentSyncEvent
201+
fields = ("id", "env_sync", "status", "created_at", "completed_at", "meta")
202+
203+
204+
class EnvironmentSyncType(DjangoObjectType):
205+
service_info = graphene.Field(ServiceType)
206+
history = graphene.List(NonNull(EnvironmentSyncEventType), required=True)
207+
208+
class Meta:
209+
model = EnvironmentSync
210+
fields = (
211+
"id",
212+
"environment",
213+
"path",
214+
"service_info",
215+
"options",
216+
"is_active",
217+
"created_at",
218+
"last_sync",
219+
"status",
220+
"authentication",
221+
"history",
222+
)
223+
224+
def resolve_service_info(self, info):
225+
service_config = ServiceConfig.get_service_config(self.service.lower())
226+
return service_config
227+
228+
def resolve_history(self, info):
229+
return EnvironmentSyncEvent.objects.filter(env_sync=self).order_by(
230+
"-created_at"
231+
)
232+
233+
179234
class EnvironmentType(DjangoObjectType):
180235
folder_count = graphene.Int()
181236
secret_count = graphene.Int()
182-
members = graphene.List(OrganisationMemberType)
237+
members = graphene.NonNull(graphene.List(OrganisationMemberType))
238+
syncs = graphene.NonNull(graphene.List(EnvironmentSyncType))
183239

184240
class Meta:
185241
model = Environment
@@ -230,10 +286,14 @@ def resolve_members(self, info):
230286
)
231287
]
232288

289+
def resolve_syncs(self, info):
290+
return EnvironmentSync.objects.filter(environment=self)
291+
233292

234293
class AppType(DjangoObjectType):
235294
sse_enabled = graphene.Boolean()
236-
environments = graphene.List(EnvironmentType)
295+
environments = graphene.NonNull(graphene.List(EnvironmentType))
296+
members = graphene.NonNull(graphene.List(OrganisationMemberType))
237297

238298
class Meta:
239299
model = App
@@ -269,6 +329,9 @@ def resolve_environments(self, info):
269329
).exists()
270330
]
271331

332+
def resolve_members(self, info):
333+
return self.members.filter(deleted_at=None)
334+
272335

273336
class EnvironmentKeyType(DjangoObjectType):
274337
class Meta:
@@ -312,25 +375,6 @@ class Meta:
312375
)
313376

314377

315-
class ProviderType(graphene.ObjectType):
316-
id = graphene.String(required=True)
317-
name = graphene.String(required=True)
318-
expected_credentials = graphene.List(
319-
graphene.NonNull(graphene.String), required=True
320-
)
321-
optional_credentials = graphene.List(
322-
graphene.NonNull(graphene.String), required=True
323-
)
324-
auth_scheme = graphene.String()
325-
326-
327-
class ServiceType(ObjectType):
328-
id = graphene.String()
329-
name = graphene.String()
330-
resource_type = graphene.String()
331-
provider = graphene.Field(ProviderType)
332-
333-
334378
class ProviderCredentialsType(DjangoObjectType):
335379
sync_count = graphene.Int()
336380
provider = graphene.Field(ProviderType)
@@ -359,42 +403,6 @@ def resolve_credentials(self, info):
359403
return get_credentials(self.id)
360404

361405

362-
class EnvironmentSyncEventType(DjangoObjectType):
363-
class Meta:
364-
model = EnvironmentSyncEvent
365-
fields = ("id", "env_sync", "status", "created_at", "completed_at", "meta")
366-
367-
368-
class EnvironmentSyncType(DjangoObjectType):
369-
service_info = graphene.Field(ServiceType)
370-
history = graphene.List(NonNull(EnvironmentSyncEventType), required=True)
371-
372-
class Meta:
373-
model = EnvironmentSync
374-
fields = (
375-
"id",
376-
"environment",
377-
"path",
378-
"service_info",
379-
"options",
380-
"is_active",
381-
"created_at",
382-
"last_sync",
383-
"status",
384-
"authentication",
385-
"history",
386-
)
387-
388-
def resolve_service_info(self, info):
389-
service_config = ServiceConfig.get_service_config(self.service.lower())
390-
return service_config
391-
392-
def resolve_history(self, info):
393-
return EnvironmentSyncEvent.objects.filter(env_sync=self).order_by(
394-
"-created_at"
395-
)
396-
397-
398406
class UserTokenType(DjangoObjectType):
399407
class Meta:
400408
model = UserToken

frontend/apollo/gql.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const documents = {
6868
"query GetAppActivityChart($appId: ID!, $period: TimeRange) {\n appActivityChart(appId: $appId, period: $period) {\n index\n date\n data\n }\n}": types.GetAppActivityChartDocument,
6969
"query GetAppDetail($organisationId: ID!, $appId: ID!) {\n apps(organisationId: $organisationId, appId: $appId) {\n id\n name\n identityKey\n createdAt\n appToken\n appSeed\n appVersion\n sseEnabled\n }\n}": types.GetAppDetailDocument,
7070
"query GetAppKmsLogs($appId: ID!, $start: BigInt, $end: BigInt) {\n logs(appId: $appId, start: $start, end: $end) {\n kms {\n id\n timestamp\n phaseNode\n eventType\n ipAddress\n country\n city\n phSize\n }\n }\n kmsLogsCount(appId: $appId)\n}": types.GetAppKmsLogsDocument,
71-
"query GetApps($organisationId: ID!, $appId: ID) {\n apps(organisationId: $organisationId, appId: $appId) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n }\n}": types.GetAppsDocument,
71+
"query GetApps($organisationId: ID!, $appId: ID) {\n apps(organisationId: $organisationId, appId: $appId) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n members {\n id\n email\n fullName\n avatarUrl\n }\n environments {\n id\n name\n envType\n syncs {\n id\n serviceInfo {\n id\n name\n provider {\n id\n name\n }\n }\n status\n }\n }\n }\n}": types.GetAppsDocument,
7272
"query GetDashboard($organisationId: ID!) {\n apps(organisationId: $organisationId) {\n id\n sseEnabled\n }\n userTokens(organisationId: $organisationId) {\n id\n }\n organisationInvites(orgId: $organisationId) {\n id\n }\n organisationMembers(organisationId: $organisationId, role: null) {\n id\n }\n savedCredentials(orgId: $organisationId) {\n id\n }\n syncs(orgId: $organisationId) {\n id\n }\n}": types.GetDashboardDocument,
7373
"query GetOrganisations {\n organisations {\n id\n name\n identityKey\n createdAt\n plan\n planDetail {\n name\n maxUsers\n maxApps\n maxEnvsPerApp\n userCount\n appCount\n }\n role\n memberId\n keyring\n recovery\n }\n}": types.GetOrganisationsDocument,
7474
"query CheckOrganisationNameAvailability($name: String!) {\n organisationNameAvailable(name: $name)\n}": types.CheckOrganisationNameAvailabilityDocument,
@@ -88,7 +88,7 @@ const documents = {
8888
"query GetSecretTags($orgId: ID!) {\n secretTags(orgId: $orgId) {\n id\n name\n color\n }\n}": types.GetSecretTagsDocument,
8989
"query GetSecrets($appId: ID!, $envId: ID!, $path: String) {\n secrets(envId: $envId, path: $path) {\n id\n key\n value\n path\n tags {\n id\n name\n color\n }\n comment\n createdAt\n history {\n id\n key\n value\n tags {\n id\n name\n color\n }\n version\n comment\n timestamp\n ipAddress\n userAgent\n user {\n email\n username\n fullName\n avatarUrl\n }\n eventType\n }\n override {\n value\n isActive\n }\n environment {\n id\n app {\n id\n }\n }\n }\n folders(envId: $envId, path: $path) {\n id\n name\n path\n createdAt\n folderCount\n secretCount\n }\n appEnvironments(appId: $appId, environmentId: $envId) {\n id\n name\n envType\n identityKey\n app {\n name\n }\n }\n environmentKeys(appId: $appId, environmentId: $envId) {\n id\n identityKey\n wrappedSeed\n wrappedSalt\n }\n envSyncs(envId: $envId) {\n id\n environment {\n id\n name\n envType\n }\n serviceInfo {\n id\n name\n }\n options\n isActive\n status\n lastSync\n createdAt\n }\n}": types.GetSecretsDocument,
9090
"query GetServiceTokens($appId: ID!) {\n serviceTokens(appId: $appId) {\n id\n name\n createdAt\n createdBy {\n fullName\n avatarUrl\n self\n }\n expiresAt\n keys {\n id\n identityKey\n }\n }\n}": types.GetServiceTokensDocument,
91-
"query GetOrganisationSyncs($orgId: ID!) {\n syncs(orgId: $orgId) {\n id\n environment {\n id\n name\n envType\n app {\n id\n name\n }\n }\n path\n serviceInfo {\n id\n name\n provider {\n id\n }\n }\n options\n isActive\n lastSync\n status\n authentication {\n id\n name\n credentials\n }\n createdAt\n history {\n id\n status\n createdAt\n completedAt\n meta\n }\n }\n savedCredentials(orgId: $orgId) {\n id\n name\n credentials\n createdAt\n provider {\n id\n name\n expectedCredentials\n optionalCredentials\n }\n syncCount\n }\n apps(organisationId: $orgId, appId: null) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n }\n}": types.GetOrganisationSyncsDocument,
91+
"query GetOrganisationSyncs($orgId: ID!) {\n syncs(orgId: $orgId) {\n id\n environment {\n id\n name\n envType\n app {\n id\n name\n }\n }\n path\n serviceInfo {\n id\n name\n provider {\n id\n }\n }\n options\n isActive\n lastSync\n status\n authentication {\n id\n name\n credentials\n }\n createdAt\n history {\n id\n status\n createdAt\n completedAt\n meta\n }\n }\n savedCredentials(orgId: $orgId) {\n id\n name\n credentials\n createdAt\n provider {\n id\n name\n expectedCredentials\n optionalCredentials\n }\n syncCount\n }\n apps(organisationId: $orgId, appId: null) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n members {\n id\n }\n environments {\n id\n name\n syncs {\n id\n serviceInfo {\n id\n name\n provider {\n id\n name\n }\n }\n status\n }\n }\n }\n}": types.GetOrganisationSyncsDocument,
9292
"query GetAwsSecrets($credentialId: ID!) {\n awsSecrets(credentialId: $credentialId) {\n name\n arn\n }\n}": types.GetAwsSecretsDocument,
9393
"query GetCfPages($credentialId: ID!) {\n cloudflarePagesProjects(credentialId: $credentialId) {\n name\n deploymentId\n environments\n }\n}": types.GetCfPagesDocument,
9494
"query GetAppSyncStatus($appId: ID!) {\n sseEnabled(appId: $appId)\n syncs(appId: $appId) {\n id\n environment {\n id\n name\n envType\n app {\n id\n name\n }\n }\n path\n serviceInfo {\n id\n name\n provider {\n id\n }\n }\n options\n isActive\n lastSync\n status\n authentication {\n id\n name\n credentials\n }\n createdAt\n history {\n id\n status\n createdAt\n completedAt\n meta\n }\n }\n serverPublicKey\n}": types.GetAppSyncStatusDocument,
@@ -341,7 +341,7 @@ export function graphql(source: "query GetAppKmsLogs($appId: ID!, $start: BigInt
341341
/**
342342
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
343343
*/
344-
export function graphql(source: "query GetApps($organisationId: ID!, $appId: ID) {\n apps(organisationId: $organisationId, appId: $appId) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n }\n}"): (typeof documents)["query GetApps($organisationId: ID!, $appId: ID) {\n apps(organisationId: $organisationId, appId: $appId) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n }\n}"];
344+
export function graphql(source: "query GetApps($organisationId: ID!, $appId: ID) {\n apps(organisationId: $organisationId, appId: $appId) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n members {\n id\n email\n fullName\n avatarUrl\n }\n environments {\n id\n name\n envType\n syncs {\n id\n serviceInfo {\n id\n name\n provider {\n id\n name\n }\n }\n status\n }\n }\n }\n}"): (typeof documents)["query GetApps($organisationId: ID!, $appId: ID) {\n apps(organisationId: $organisationId, appId: $appId) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n members {\n id\n email\n fullName\n avatarUrl\n }\n environments {\n id\n name\n envType\n syncs {\n id\n serviceInfo {\n id\n name\n provider {\n id\n name\n }\n }\n status\n }\n }\n }\n}"];
345345
/**
346346
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
347347
*/
@@ -421,7 +421,7 @@ export function graphql(source: "query GetServiceTokens($appId: ID!) {\n servic
421421
/**
422422
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
423423
*/
424-
export function graphql(source: "query GetOrganisationSyncs($orgId: ID!) {\n syncs(orgId: $orgId) {\n id\n environment {\n id\n name\n envType\n app {\n id\n name\n }\n }\n path\n serviceInfo {\n id\n name\n provider {\n id\n }\n }\n options\n isActive\n lastSync\n status\n authentication {\n id\n name\n credentials\n }\n createdAt\n history {\n id\n status\n createdAt\n completedAt\n meta\n }\n }\n savedCredentials(orgId: $orgId) {\n id\n name\n credentials\n createdAt\n provider {\n id\n name\n expectedCredentials\n optionalCredentials\n }\n syncCount\n }\n apps(organisationId: $orgId, appId: null) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n }\n}"): (typeof documents)["query GetOrganisationSyncs($orgId: ID!) {\n syncs(orgId: $orgId) {\n id\n environment {\n id\n name\n envType\n app {\n id\n name\n }\n }\n path\n serviceInfo {\n id\n name\n provider {\n id\n }\n }\n options\n isActive\n lastSync\n status\n authentication {\n id\n name\n credentials\n }\n createdAt\n history {\n id\n status\n createdAt\n completedAt\n meta\n }\n }\n savedCredentials(orgId: $orgId) {\n id\n name\n credentials\n createdAt\n provider {\n id\n name\n expectedCredentials\n optionalCredentials\n }\n syncCount\n }\n apps(organisationId: $orgId, appId: null) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n }\n}"];
424+
export function graphql(source: "query GetOrganisationSyncs($orgId: ID!) {\n syncs(orgId: $orgId) {\n id\n environment {\n id\n name\n envType\n app {\n id\n name\n }\n }\n path\n serviceInfo {\n id\n name\n provider {\n id\n }\n }\n options\n isActive\n lastSync\n status\n authentication {\n id\n name\n credentials\n }\n createdAt\n history {\n id\n status\n createdAt\n completedAt\n meta\n }\n }\n savedCredentials(orgId: $orgId) {\n id\n name\n credentials\n createdAt\n provider {\n id\n name\n expectedCredentials\n optionalCredentials\n }\n syncCount\n }\n apps(organisationId: $orgId, appId: null) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n members {\n id\n }\n environments {\n id\n name\n syncs {\n id\n serviceInfo {\n id\n name\n provider {\n id\n name\n }\n }\n status\n }\n }\n }\n}"): (typeof documents)["query GetOrganisationSyncs($orgId: ID!) {\n syncs(orgId: $orgId) {\n id\n environment {\n id\n name\n envType\n app {\n id\n name\n }\n }\n path\n serviceInfo {\n id\n name\n provider {\n id\n }\n }\n options\n isActive\n lastSync\n status\n authentication {\n id\n name\n credentials\n }\n createdAt\n history {\n id\n status\n createdAt\n completedAt\n meta\n }\n }\n savedCredentials(orgId: $orgId) {\n id\n name\n credentials\n createdAt\n provider {\n id\n name\n expectedCredentials\n optionalCredentials\n }\n syncCount\n }\n apps(organisationId: $orgId, appId: null) {\n id\n name\n identityKey\n createdAt\n sseEnabled\n members {\n id\n }\n environments {\n id\n name\n syncs {\n id\n serviceInfo {\n id\n name\n provider {\n id\n name\n }\n }\n status\n }\n }\n }\n}"];
425425
/**
426426
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
427427
*/

0 commit comments

Comments
 (0)