From 2158a71e922dca86158d0ec4aeeb0eeab333ef74 Mon Sep 17 00:00:00 2001 From: Patryk Ziemkowski Date: Wed, 22 Nov 2023 12:48:38 +0100 Subject: [PATCH] Workshop #1 --- package.json | 2 +- packages/backend/apps/workshops/__init__.py | 0 packages/backend/apps/workshops/admin.py | 8 ++++ packages/backend/apps/workshops/apps.py | 6 +++ .../apps/workshops/migrations/0001_initial.py | 29 ++++++++++++++ .../apps/workshops/migrations/__init__.py | 0 packages/backend/apps/workshops/models.py | 9 +++++ packages/backend/apps/workshops/schema.py | 26 +++++++++++++ packages/backend/apps/workshops/tests.py | 3 ++ packages/backend/apps/workshops/views.py | 3 ++ packages/backend/config/schema.py | 11 +++++- packages/backend/config/settings.py | 1 + .../src/stacks/ci/ciServerless.ts | 1 - .../graphql/schema/api.graphql | 23 ++++++++++- .../src/graphql/__generated/gql/gql.ts | 5 +++ .../src/graphql/__generated/gql/graphql.ts | 39 +++++++++++++++++++ packages/webapp/src/app/app.component.tsx | 3 +- packages/webapp/src/app/asyncComponents.ts | 2 + packages/webapp/src/app/config/routes.ts | 6 ++- .../workshops/workshopItemsList/index.ts | 1 + .../workshopItemsList.components.tsx | 32 +++++++++++++++ pnpm-lock.yaml | 17 ++++---- 22 files changed, 212 insertions(+), 15 deletions(-) create mode 100644 packages/backend/apps/workshops/__init__.py create mode 100644 packages/backend/apps/workshops/admin.py create mode 100644 packages/backend/apps/workshops/apps.py create mode 100644 packages/backend/apps/workshops/migrations/0001_initial.py create mode 100644 packages/backend/apps/workshops/migrations/__init__.py create mode 100644 packages/backend/apps/workshops/models.py create mode 100644 packages/backend/apps/workshops/schema.py create mode 100644 packages/backend/apps/workshops/tests.py create mode 100644 packages/backend/apps/workshops/views.py create mode 100644 packages/webapp/src/routes/workshops/workshopItemsList/index.ts create mode 100644 packages/webapp/src/routes/workshops/workshopItemsList/workshopItemsList.components.tsx diff --git a/package.json b/package.json index de81947..523fa73 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ }, "devDependencies": { "@apollo/client": "^3.8.4", - "@apollo/rover": "^0.19.0", + "@apollo/rover": "^0.21.0", "@babel/preset-react": "^7.22.15", "@graphql-codegen/cli": "^5.0.0", "@graphql-typed-document-node/core": "^3.2.0", diff --git a/packages/backend/apps/workshops/__init__.py b/packages/backend/apps/workshops/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/packages/backend/apps/workshops/admin.py b/packages/backend/apps/workshops/admin.py new file mode 100644 index 0000000..97c8dae --- /dev/null +++ b/packages/backend/apps/workshops/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin + +from . import models + + +@admin.register(models.WorkshopItem) +class WorkshopItemAdmin(admin.ModelAdmin): + list_display = ('id', 'name') diff --git a/packages/backend/apps/workshops/apps.py b/packages/backend/apps/workshops/apps.py new file mode 100644 index 0000000..ac0eeb2 --- /dev/null +++ b/packages/backend/apps/workshops/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class WorkshopsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'apps.workshops' diff --git a/packages/backend/apps/workshops/migrations/0001_initial.py b/packages/backend/apps/workshops/migrations/0001_initial.py new file mode 100644 index 0000000..fac9fb0 --- /dev/null +++ b/packages/backend/apps/workshops/migrations/0001_initial.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2 on 2023-09-27 12:41 + +from django.db import migrations, models +import hashid_field.field + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name='WorkshopItem', + fields=[ + ( + 'id', + hashid_field.field.HashidAutoField( + alphabet='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890', + min_length=7, + prefix='', + primary_key=True, + serialize=False, + ), + ), + ('name', models.CharField(max_length=255)), + ], + ), + ] diff --git a/packages/backend/apps/workshops/migrations/__init__.py b/packages/backend/apps/workshops/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/packages/backend/apps/workshops/models.py b/packages/backend/apps/workshops/models.py new file mode 100644 index 0000000..7affc1c --- /dev/null +++ b/packages/backend/apps/workshops/models.py @@ -0,0 +1,9 @@ +import hashid_field + +from django.db import models + + +# Create your models here. +class WorkshopItem(models.Model): + id = hashid_field.HashidAutoField(primary_key=True) + name = models.CharField(max_length=255) diff --git a/packages/backend/apps/workshops/schema.py b/packages/backend/apps/workshops/schema.py new file mode 100644 index 0000000..1bf115c --- /dev/null +++ b/packages/backend/apps/workshops/schema.py @@ -0,0 +1,26 @@ +import graphene + +from graphene import relay +from graphene_django import DjangoObjectType + +from . import models + + +class WorkshopItemType(DjangoObjectType): + class Meta: + model = models.WorkshopItem + interfaces = (relay.Node,) + fields = '__all__' + + +class WorkshopItemConnection(graphene.Connection): + class Meta: + node = WorkshopItemType + + +class Query(graphene.ObjectType): + all_workshop_items = graphene.relay.ConnectionField(WorkshopItemConnection) + + @staticmethod + def resolve_all_workshop_items(root, info, **kwargs): + return models.WorkshopItem.objects.all() diff --git a/packages/backend/apps/workshops/tests.py b/packages/backend/apps/workshops/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/packages/backend/apps/workshops/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/packages/backend/apps/workshops/views.py b/packages/backend/apps/workshops/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/packages/backend/apps/workshops/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/packages/backend/config/schema.py b/packages/backend/config/schema.py index 32acc05..6d4ec5d 100644 --- a/packages/backend/config/schema.py +++ b/packages/backend/config/schema.py @@ -5,10 +5,19 @@ from apps.notifications import schema as notifications_schema from apps.users import schema as users_schema from apps.integrations import schema as integrations_schema +from apps.workshops import schema as workshops_schema from common.graphql.utils import graphql_query, graphql_mutation, graphql_subscription schema = graphene.Schema( - query=graphql_query([demo_schema.Query, notifications_schema.Query, users_schema.Query, finances_schema.Query]), + query=graphql_query( + [ + demo_schema.Query, + notifications_schema.Query, + users_schema.Query, + finances_schema.Query, + workshops_schema.Query, + ] + ), mutation=graphql_mutation( [ demo_schema.Mutation, diff --git a/packages/backend/config/settings.py b/packages/backend/config/settings.py index fc09a75..c9ac94b 100644 --- a/packages/backend/config/settings.py +++ b/packages/backend/config/settings.py @@ -61,6 +61,7 @@ "apps.notifications", "apps.websockets", "apps.integrations", + "apps.workshops", ] INSTALLED_APPS = DJANGO_CORE_APPS + THIRD_PARTY_APPS + LOCAL_APPS diff --git a/packages/infra/infra-shared/src/stacks/ci/ciServerless.ts b/packages/infra/infra-shared/src/stacks/ci/ciServerless.ts index b222eb5..13c43df 100644 --- a/packages/infra/infra-shared/src/stacks/ci/ciServerless.ts +++ b/packages/infra/infra-shared/src/stacks/ci/ciServerless.ts @@ -95,7 +95,6 @@ export class ServerlessCiConfig extends ServiceCiConfig { build: { commands: [ `pnpm saas workers lint`, - 'pnpm saas emails build', `pnpm saas workers test`, ], }, diff --git a/packages/webapp-libs/webapp-api-client/graphql/schema/api.graphql b/packages/webapp-libs/webapp-api-client/graphql/schema/api.graphql index 8498089..a13885f 100644 --- a/packages/webapp-libs/webapp-api-client/graphql/schema/api.graphql +++ b/packages/webapp-libs/webapp-api-client/graphql/schema/api.graphql @@ -36,6 +36,7 @@ that will be handled by the multipart request spec """ scalar Upload type Query { + allWorkshopItems(before: String, after: String, first: Int, last: Int): WorkshopItemConnection allSubscriptionPlans(before: String, after: String, first: Int, last: Int): StripePriceConnection activeSubscription: SubscriptionScheduleType allPaymentMethods(before: String, after: String, first: Int, last: Int): PaymentMethodConnection @@ -57,11 +58,11 @@ type Query { id: ID! ): Node } -type StripePriceConnection { +type WorkshopItemConnection { "Pagination data for this connection." pageInfo: PageInfo! "Contains the nodes in this connection." - edges: [StripePriceEdge]! + edges: [WorkshopItemEdge]! } "The Relay compliant `PageInfo` type, containing data necessary to paginate this connection." type PageInfo { @@ -74,6 +75,24 @@ type PageInfo { "When paginating forwards, the cursor to continue." endCursor: String } +"A Relay edge containing a `WorkshopItem` and its cursor." +type WorkshopItemEdge { + "The item at the end of the edge" + node: WorkshopItemType + "A cursor for use in pagination" + cursor: String! +} +type WorkshopItemType implements Node { + "The ID of the object" + id: ID! + name: String! +} +type StripePriceConnection { + "Pagination data for this connection." + pageInfo: PageInfo! + "Contains the nodes in this connection." + edges: [StripePriceEdge]! +} "A Relay edge containing a `StripePrice` and its cursor." type StripePriceEdge { "The item at the end of the edge" diff --git a/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/gql.ts b/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/gql.ts index 62f2ec1..b6186df 100644 --- a/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/gql.ts +++ b/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/gql.ts @@ -63,6 +63,7 @@ const documents = { "\n fragment notificationsListContentFragment on Query {\n hasUnreadNotifications\n allNotifications(first: $count, after: $cursor) {\n edges {\n node {\n id\n data\n createdAt\n readAt\n type\n issuer {\n id\n avatar\n email\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n": types.NotificationsListContentFragmentFragmentDoc, "\n mutation notificationsListMarkAsReadMutation($input: MarkReadAllNotificationsMutationInput!) {\n markReadAllNotifications(input: $input) {\n ok\n }\n }\n": types.NotificationsListMarkAsReadMutationDocument, "\n mutation authConfirmUserEmailMutation($input: ConfirmEmailMutationInput!) {\n confirm(input: $input) {\n ok\n }\n }\n": types.AuthConfirmUserEmailMutationDocument, + "\n query WorkshopItemsList {\n allWorkshopItems {\n edges {\n node {\n id\n name\n }\n }\n }\n }\n": types.WorkshopItemsListDocument, "\n mutation authChangePasswordMutation($input: ChangePasswordMutationInput!) {\n changePassword(input: $input) {\n access\n refresh\n }\n }\n": types.AuthChangePasswordMutationDocument, "\n mutation authUpdateUserProfileMutation($input: UpdateCurrentUserMutationInput!) {\n updateCurrentUser(input: $input) {\n userProfile {\n id\n user {\n ...commonQueryCurrentUserFragment\n }\n }\n }\n }\n": types.AuthUpdateUserProfileMutationDocument, "\n mutation loginFormMutation($input: ObtainTokenMutationInput!) {\n tokenAuth(input: $input) {\n access\n refresh\n otpAuthToken\n }\n }\n": types.LoginFormMutationDocument, @@ -289,6 +290,10 @@ export function gql(source: "\n mutation notificationsListMarkAsReadMutation($i * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function gql(source: "\n mutation authConfirmUserEmailMutation($input: ConfirmEmailMutationInput!) {\n confirm(input: $input) {\n ok\n }\n }\n"): (typeof documents)["\n mutation authConfirmUserEmailMutation($input: ConfirmEmailMutationInput!) {\n confirm(input: $input) {\n ok\n }\n }\n"]; +/** + * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function gql(source: "\n query WorkshopItemsList {\n allWorkshopItems {\n edges {\n node {\n id\n name\n }\n }\n }\n }\n"): (typeof documents)["\n query WorkshopItemsList {\n allWorkshopItems {\n edges {\n node {\n id\n name\n }\n }\n }\n }\n"]; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/graphql.ts b/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/graphql.ts index 61333e7..fe98537 100644 --- a/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/graphql.ts +++ b/packages/webapp-libs/webapp-api-client/src/graphql/__generated/gql/graphql.ts @@ -1695,6 +1695,7 @@ export type Query = { allNotifications?: Maybe; allPaymentMethods?: Maybe; allSubscriptionPlans?: Maybe; + allWorkshopItems?: Maybe; appConfig?: Maybe; appConfigCollection?: Maybe; asset?: Maybe; @@ -1767,6 +1768,14 @@ export type QueryAllSubscriptionPlansArgs = { }; +export type QueryAllWorkshopItemsArgs = { + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; +}; + + export type QueryAppConfigArgs = { id: Scalars['String']['input']; locale?: InputMaybe; @@ -2649,6 +2658,30 @@ export type VerifyOtpMutationPayload = { otpVerified?: Maybe; }; +export type WorkshopItemConnection = { + __typename?: 'WorkshopItemConnection'; + /** Contains the nodes in this connection. */ + edges: Array>; + /** Pagination data for this connection. */ + pageInfo: PageInfo; +}; + +/** A Relay edge containing a `WorkshopItem` and its cursor. */ +export type WorkshopItemEdge = { + __typename?: 'WorkshopItemEdge'; + /** A cursor for use in pagination */ + cursor: Scalars['String']['output']; + /** The item at the end of the edge */ + node?: Maybe; +}; + +export type WorkshopItemType = Node & { + __typename?: 'WorkshopItemType'; + /** The ID of the object */ + id: Scalars['ID']['output']; + name: Scalars['String']['output']; +}; + export type PaginationListTestQueryQueryVariables = Exact<{ first?: InputMaybe; after?: InputMaybe; @@ -2997,6 +3030,11 @@ export type AuthConfirmUserEmailMutationMutationVariables = Exact<{ export type AuthConfirmUserEmailMutationMutation = { __typename?: 'ApiMutation', confirm?: { __typename?: 'ConfirmEmailMutationPayload', ok?: boolean | null } | null }; +export type WorkshopItemsListQueryVariables = Exact<{ [key: string]: never; }>; + + +export type WorkshopItemsListQuery = { __typename?: 'Query', allWorkshopItems?: { __typename?: 'WorkshopItemConnection', edges: Array<{ __typename?: 'WorkshopItemEdge', node?: { __typename?: 'WorkshopItemType', id: string, name: string } | null } | null> } | null }; + export type AuthChangePasswordMutationMutationVariables = Exact<{ input: ChangePasswordMutationInput; }>; @@ -3122,6 +3160,7 @@ export const NotificationsListQueryDocument = {"kind":"Document","definitions":[ export const NotificationsListSubscriptionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"notificationsListSubscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"notificationCreated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"readAt"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const NotificationsListMarkAsReadMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"notificationsListMarkAsReadMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"MarkReadAllNotificationsMutationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"markReadAllNotifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"ok"}}]}}]}}]} as unknown as DocumentNode; export const AuthConfirmUserEmailMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"authConfirmUserEmailMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ConfirmEmailMutationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"confirm"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"ok"}}]}}]}}]} as unknown as DocumentNode; +export const WorkshopItemsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"WorkshopItemsList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"allWorkshopItems"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const AuthChangePasswordMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"authChangePasswordMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ChangePasswordMutationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"changePassword"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"access"}},{"kind":"Field","name":{"kind":"Name","value":"refresh"}}]}}]}}]} as unknown as DocumentNode; export const AuthUpdateUserProfileMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"authUpdateUserProfileMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateCurrentUserMutationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateCurrentUser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userProfile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"commonQueryCurrentUserFragment"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"commonQueryCurrentUserFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CurrentUserType"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"roles"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"otpVerified"}},{"kind":"Field","name":{"kind":"Name","value":"otpEnabled"}}]}}]} as unknown as DocumentNode; export const LoginFormMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"loginFormMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ObtainTokenMutationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tokenAuth"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"access"}},{"kind":"Field","name":{"kind":"Name","value":"refresh"}},{"kind":"Field","name":{"kind":"Name","value":"otpAuthToken"}}]}}]}}]} as unknown as DocumentNode; diff --git a/packages/webapp/src/app/app.component.tsx b/packages/webapp/src/app/app.component.tsx index 80e2ce7..425978c 100644 --- a/packages/webapp/src/app/app.component.tsx +++ b/packages/webapp/src/app/app.component.tsx @@ -23,7 +23,7 @@ import { Admin } from '../routes/admin'; import { PasswordReset } from '../routes/auth/passwordReset'; import ValidateOtp from '../routes/auth/validateOtp'; import { AnonymousRoute, AuthRoute } from '../shared/components/routes'; -import { ConfirmEmail, Home, Login, Logout, NotFound, Profile, Signup } from './asyncComponents'; +import { ConfirmEmail, Home, Login, Logout, NotFound, Profile, Signup, WorkshopItemsList } from './asyncComponents'; import { LANG_PREFIX, RoutesConfig } from './config/routes'; import { ValidRoutesProviders } from './providers'; @@ -65,6 +65,7 @@ export const App = () => { } /> } /> } /> + } /> } /> }> diff --git a/packages/webapp/src/app/asyncComponents.ts b/packages/webapp/src/app/asyncComponents.ts index c7efaba..cedd14f 100644 --- a/packages/webapp/src/app/asyncComponents.ts +++ b/packages/webapp/src/app/asyncComponents.ts @@ -7,4 +7,6 @@ export const Login = asyncComponent(() => import('../routes/auth/login')); export const Logout = asyncComponent(() => import('../routes/auth/logout')); export const Profile = asyncComponent(() => import('../routes/profile')); export const ConfirmEmail = asyncComponent(() => import('../routes/auth/confirmEmail')); + +export const WorkshopItemsList = asyncComponent(() => import('../routes/workshops/workshopItemsList')); //<-- IMPORT ROUTE --> diff --git a/packages/webapp/src/app/config/routes.ts b/packages/webapp/src/app/config/routes.ts index d300305..0c68cdd 100644 --- a/packages/webapp/src/app/config/routes.ts +++ b/packages/webapp/src/app/config/routes.ts @@ -1,6 +1,6 @@ import { RoutesConfig as ContentfulRoutesConfig } from '@sb/webapp-contentful/config/routes'; import { RoutesConfig as CoreRoutesConfig } from '@sb/webapp-core/config/routes'; -import { getLocalePath } from '@sb/webapp-core/utils/path'; +import { getLocalePath, nestedPath } from '@sb/webapp-core/utils/path'; import { RoutesConfig as CrudDemoRoutesConfig } from '@sb/webapp-crud-demo/config/routes'; import { RoutesConfig as FinancesRoutesConfig } from '@sb/webapp-finances/config/routes'; import { RoutesConfig as GenerativeAIRoutesConfig } from '@sb/webapp-generative-ai/config/routes'; @@ -10,6 +10,10 @@ export const LANG_PREFIX = `/:lang?/*`; export const RoutesConfig = { ...CoreRoutesConfig, documents: 'documents', + workshops: nestedPath('workshops', { + list: 'list', + create: 'create', + }), ...GenerativeAIRoutesConfig, ...ContentfulRoutesConfig, ...CrudDemoRoutesConfig, diff --git a/packages/webapp/src/routes/workshops/workshopItemsList/index.ts b/packages/webapp/src/routes/workshops/workshopItemsList/index.ts new file mode 100644 index 0000000..6a5f16c --- /dev/null +++ b/packages/webapp/src/routes/workshops/workshopItemsList/index.ts @@ -0,0 +1 @@ +export { WorkshopItemsList as default } from './workshopItemsList.components'; diff --git a/packages/webapp/src/routes/workshops/workshopItemsList/workshopItemsList.components.tsx b/packages/webapp/src/routes/workshops/workshopItemsList/workshopItemsList.components.tsx new file mode 100644 index 0000000..85e5f28 --- /dev/null +++ b/packages/webapp/src/routes/workshops/workshopItemsList/workshopItemsList.components.tsx @@ -0,0 +1,32 @@ +import { useQuery } from '@apollo/client'; +import { gql } from '@sb/webapp-api-client'; +import { FC } from 'react'; + +export const workshopItemsListQuery = gql(/* GraphQL */ ` + query WorkshopItemsList { + allWorkshopItems { + edges { + node { + id + name + } + } + } + } +`); + +export const WorkshopItemsList: FC = () => { + const { data, loading } = useQuery(workshopItemsListQuery); + + if (loading) { + return

Loading...

; + } + + return ( +
    + {data?.allWorkshopItems?.edges?.map((edge) => { + return
  • {edge?.node?.name}
  • ; + })} +
+ ); +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02280bd..b84c7c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -88,8 +88,8 @@ importers: specifier: ^3.8.4 version: 3.8.4(graphql-ws@5.14.0)(graphql@16.8.1)(react-dom@18.2.0)(react@18.2.0) '@apollo/rover': - specifier: ^0.19.0 - version: 0.19.0 + specifier: ^0.21.0 + version: 0.21.0 '@babel/preset-react': specifier: ^7.22.15 version: 7.22.15(@babel/core@7.22.20) @@ -1244,8 +1244,8 @@ packages: tslib: 2.6.2 zen-observable-ts: 1.2.5 - /@apollo/rover@0.19.0: - resolution: {integrity: sha512-Q75Db4gxo0uN4+gF3vE2TyHQgJOgvQFad1Ep/GySSe+j2DxrFgWYiYBvILztaXJweDiE2yYRgV8wHhjyOpxR6g==} + /@apollo/rover@0.21.0: + resolution: {integrity: sha512-bi5R5zHw+qmHJO1uovCCF7QzhBRH6BMZlFcw28JVFul47O5LKMl+OEJGe7LPbvPOrvmlkmfupHXeYZ/jT9yRqA==} engines: {node: '>=14', npm: '>=6'} hasBin: true requiresBuild: true @@ -13622,14 +13622,14 @@ packages: /axios@0.21.4: resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.3 transitivePeerDependencies: - debug /axios@0.25.0: resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==} dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.3 transitivePeerDependencies: - debug dev: false @@ -13637,7 +13637,7 @@ packages: /axios@0.26.1: resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.3 transitivePeerDependencies: - debug dev: true @@ -18972,6 +18972,7 @@ packages: peerDependenciesMeta: debug: optional: true + dev: true /follow-redirects@1.15.3: resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} @@ -20161,7 +20162,7 @@ packages: engines: {node: '>=8.0.0'} dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.2 + follow-redirects: 1.15.3 requires-port: 1.0.0 transitivePeerDependencies: - debug