@eventcatalog/core 0.0.7 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -0
- package/.next/build-manifest.json +110 -0
- package/.next/cache/.tsbuildinfo +1 -0
- package/.next/cache/config.json +7 -0
- package/.next/cache/eslint/.cache_1bay4w0 +1 -0
- package/.next/cache/next-server.js.nft.json +1 -0
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/export-marker.json +1 -0
- package/.next/images-manifest.json +1 -0
- package/.next/next-server.js.nft.json +1 -0
- package/.next/prerender-manifest.json +1 -0
- package/.next/react-loadable-manifest.json +1717 -0
- package/.next/required-server-files.json +1 -0
- package/.next/routes-manifest.json +1 -0
- package/.next/server/chunks/237.js +116 -0
- package/.next/server/chunks/428.js +84 -0
- package/.next/server/chunks/47.js +51 -0
- package/.next/server/chunks/526.js +131 -0
- package/.next/server/chunks/565.js +121 -0
- package/.next/server/chunks/596.js +98 -0
- package/.next/server/chunks/730.js +320 -0
- package/.next/server/chunks/8.js +122 -0
- package/.next/server/chunks/938.js +109 -0
- package/.next/server/chunks/944.js +646 -0
- package/.next/server/chunks/959.js +286 -0
- package/.next/server/chunks/97.js +1837 -0
- package/.next/server/chunks/font-manifest.json +1 -0
- package/.next/server/font-manifest.json +1 -0
- package/.next/server/middleware-manifest.json +6 -0
- package/.next/server/pages/404.html +1 -0
- package/.next/server/pages/500.html +1 -0
- package/.next/server/pages/_app.js +370 -0
- package/.next/server/pages/_app.js.nft.json +1 -0
- package/.next/server/pages/_document.js +1004 -0
- package/.next/server/pages/_document.js.nft.json +1 -0
- package/.next/server/pages/_error.js +123 -0
- package/.next/server/pages/_error.js.nft.json +1 -0
- package/.next/server/pages/api/event/[name]/download.js +64 -0
- package/.next/server/pages/api/event/[name]/download.js.nft.json +1 -0
- package/.next/server/pages/events/AddedItemToCart.html +73 -0
- package/.next/server/pages/events/AddedItemToCart.json +1 -0
- package/.next/server/pages/events/OrderComplete.html +48 -0
- package/.next/server/pages/events/OrderComplete.json +1 -0
- package/.next/server/pages/events/OrderConfirmed.html +48 -0
- package/.next/server/pages/events/OrderConfirmed.json +1 -0
- package/.next/server/pages/events/OrderRequested.html +48 -0
- package/.next/server/pages/events/OrderRequested.json +1 -0
- package/.next/server/pages/events/PaymentProcessed.html +52 -0
- package/.next/server/pages/events/PaymentProcessed.json +1 -0
- package/.next/server/pages/events/RemovedItemFromCart.html +55 -0
- package/.next/server/pages/events/RemovedItemFromCart.json +1 -0
- package/.next/server/pages/events/ShipmentDelivered.html +53 -0
- package/.next/server/pages/events/ShipmentDelivered.json +1 -0
- package/.next/server/pages/events/ShipmentDispatched.html +52 -0
- package/.next/server/pages/events/ShipmentDispatched.json +1 -0
- package/.next/server/pages/events/ShipmentPrepared.html +52 -0
- package/.next/server/pages/events/ShipmentPrepared.json +1 -0
- package/.next/server/pages/events/[name]/logs.js +414 -0
- package/.next/server/pages/events/[name]/logs.js.nft.json +1 -0
- package/.next/server/pages/events/[name]/v/[version].js +267 -0
- package/.next/server/pages/events/[name]/v/[version].js.nft.json +1 -0
- package/.next/server/pages/events/[name].js +228 -0
- package/.next/server/pages/events/[name].js.nft.json +1 -0
- package/.next/server/pages/events.js +519 -0
- package/.next/server/pages/events.js.nft.json +1 -0
- package/.next/server/pages/index.html +1 -0
- package/.next/server/pages/index.js.nft.json +1 -0
- package/.next/server/pages/overview.js +240 -0
- package/.next/server/pages/overview.js.nft.json +1 -0
- package/.next/server/pages/services/Basket Service.html +11 -0
- package/.next/server/pages/services/Basket Service.json +1 -0
- package/.next/server/pages/services/Data Lake.html +12 -0
- package/.next/server/pages/services/Data Lake.json +1 -0
- package/.next/server/pages/services/Payment Service.html +10 -0
- package/.next/server/pages/services/Payment Service.json +1 -0
- package/.next/server/pages/services/Shipping Service.html +14 -0
- package/.next/server/pages/services/Shipping Service.json +1 -0
- package/.next/server/pages/services/[name].js +665 -0
- package/.next/server/pages/services/[name].js.nft.json +1 -0
- package/.next/server/pages/services.js +396 -0
- package/.next/server/pages/services.js.nft.json +1 -0
- package/.next/server/pages/users/[id].js +327 -0
- package/.next/server/pages/users/[id].js.nft.json +1 -0
- package/.next/server/pages-manifest.json +16 -0
- package/.next/server/webpack-api-runtime.js +160 -0
- package/.next/server/webpack-runtime.js +264 -0
- package/.next/static/_vd7D7jNxx4JR685n7v1G/_buildManifest.js +1 -0
- package/.next/static/_vd7D7jNxx4JR685n7v1G/_middlewareManifest.js +1 -0
- package/.next/static/_vd7D7jNxx4JR685n7v1G/_ssgManifest.js +1 -0
- package/.next/static/chunks/020d8314.aea2d24215754e7b.js +1 -0
- package/.next/static/chunks/176cb4e4-8a0f6f010ef8accb.js +1 -0
- package/.next/static/chunks/274-11c4d093341d7201.js +1 -0
- package/.next/static/chunks/336-27e73f1c995ab4e7.js +1 -0
- package/.next/static/chunks/364-3cb3c8cf1d3c95de.js +1 -0
- package/.next/static/chunks/519-7f22292093abd7c3.js +1 -0
- package/.next/static/chunks/638.d570519ae49c92c8.js +1 -0
- package/.next/static/chunks/873-cd4309ed788ee564.js +1 -0
- package/.next/static/chunks/954-4d4a09c3269dda3f.js +1 -0
- package/.next/static/chunks/962-d5070461f6d4a478.js +1 -0
- package/.next/static/chunks/framework-576ec6a1c1386453.js +1 -0
- package/.next/static/chunks/main-0289ecbd51cd4cb4.js +1 -0
- package/.next/static/chunks/pages/_app-c9d3172cc09cf069.js +1 -0
- package/.next/static/chunks/pages/_error-5a714c45c50a8db4.js +1 -0
- package/.next/static/chunks/pages/events/[name]/logs-d159d7b82f44847f.js +1 -0
- package/.next/static/chunks/pages/events/[name]/v/[version]-963d3e8377b51e86.js +1 -0
- package/.next/static/chunks/pages/events/[name]-578828157369b5cd.js +1 -0
- package/.next/static/chunks/pages/events-bcad8442f21d6b67.js +1 -0
- package/.next/static/chunks/pages/index-3eeab7e4014a02ea.js +1 -0
- package/.next/static/chunks/pages/overview-5ac749891cbe1922.js +1 -0
- package/.next/static/chunks/pages/services/[name]-8e53e76ab1c52c30.js +1 -0
- package/.next/static/chunks/pages/services-bcc61898062e1bf4.js +1 -0
- package/.next/static/chunks/pages/users/[id]-2da54ccb6319b207.js +1 -0
- package/.next/static/chunks/polyfills-5cd94c89d3acac5f.js +1 -0
- package/.next/static/chunks/webpack-afe52d4a9fcc5a75.js +1 -0
- package/.next/static/css/5eeed9cb243ce668.css +1 -0
- package/.next/static/css/b44e1178a88a93b4.css +3 -0
- package/.next/trace +37 -0
- package/CHANGELOG.md +30 -0
- package/bin/eventcatalog.js +4 -15
- package/components/ContentView.tsx +22 -29
- package/components/Grids/EventGrid.tsx +3 -13
- package/components/Grids/ServiceGrid.tsx +3 -11
- package/components/Header.tsx +1 -3
- package/components/Mdx/Examples.tsx +2 -9
- package/components/NotFound/index.tsx +16 -21
- package/components/Sidebars/EventSidebar.tsx +19 -14
- package/components/Sidebars/ServiceSidebar.tsx +26 -25
- package/eventcatalog.config.js +40 -0
- package/hooks/EventCatalog.tsx +1 -1
- package/lib/__tests__/assets/services/Basket Service/index.md +19 -0
- package/lib/__tests__/events.spec.ts +16 -27
- package/lib/__tests__/file-reader.spec.ts +3 -9
- package/lib/__tests__/services.spec.ts +27 -6
- package/lib/events.ts +4 -9
- package/lib/file-reader.ts +1 -3
- package/lib/graphs.ts +2 -4
- package/lib/services.ts +5 -11
- package/package.json +2 -2
- package/pages/_app.tsx +3 -12
- package/pages/events/[name]/logs.tsx +7 -18
- package/pages/events/[name].tsx +8 -16
- package/pages/events.tsx +5 -16
- package/pages/index.tsx +2 -9
- package/pages/overview.tsx +1 -4
- package/pages/services/[name].tsx +6 -4
- package/pages/services.tsx +2 -6
- package/pages/users/[id].tsx +4 -13
- package/scripts/__tests__/assets/eventcatalog.config.js +1 -2
- package/scripts/__tests__/generate.spec.ts +1 -4
- package/scripts/generate.js +1 -1
- package/tailwind.config.js +1 -5
- package/tsconfig.json +1 -7
|
@@ -27,12 +27,12 @@ describe('events lib', () => {
|
|
|
27
27
|
expect(event).toEqual({
|
|
28
28
|
name: 'AddedItemToCart',
|
|
29
29
|
version: '0.0.1',
|
|
30
|
-
summary:
|
|
31
|
-
'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
30
|
+
summary: 'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
32
31
|
producers: ['Shopping API', 'Application API'],
|
|
33
32
|
consumers: ['Customer Portal'],
|
|
34
33
|
owners: ['dboyne', 'mSmith'],
|
|
35
34
|
historicVersions: [],
|
|
35
|
+
externalLinks: [],
|
|
36
36
|
schema: null,
|
|
37
37
|
examples: [],
|
|
38
38
|
});
|
|
@@ -68,23 +68,11 @@ describe('events lib', () => {
|
|
|
68
68
|
const example2 = event.examples[1];
|
|
69
69
|
|
|
70
70
|
const example1File = fs.readFileSync(
|
|
71
|
-
path.join(
|
|
72
|
-
process.env.PROJECT_DIR,
|
|
73
|
-
'events',
|
|
74
|
-
'EventWithSchemaAndExamples',
|
|
75
|
-
'examples',
|
|
76
|
-
'Basic.cs'
|
|
77
|
-
),
|
|
71
|
+
path.join(process.env.PROJECT_DIR, 'events', 'EventWithSchemaAndExamples', 'examples', 'Basic.cs'),
|
|
78
72
|
{ encoding: 'utf-8' }
|
|
79
73
|
);
|
|
80
74
|
const example2File = fs.readFileSync(
|
|
81
|
-
path.join(
|
|
82
|
-
process.env.PROJECT_DIR,
|
|
83
|
-
'events',
|
|
84
|
-
'EventWithSchemaAndExamples',
|
|
85
|
-
'examples',
|
|
86
|
-
'Basic.js'
|
|
87
|
-
),
|
|
75
|
+
path.join(process.env.PROJECT_DIR, 'events', 'EventWithSchemaAndExamples', 'examples', 'Basic.js'),
|
|
88
76
|
{ encoding: 'utf-8' }
|
|
89
77
|
);
|
|
90
78
|
|
|
@@ -118,11 +106,11 @@ describe('events lib', () => {
|
|
|
118
106
|
{
|
|
119
107
|
name: 'AddedItemToCart',
|
|
120
108
|
version: '0.0.1',
|
|
121
|
-
summary:
|
|
122
|
-
'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
109
|
+
summary: 'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
123
110
|
producers: ['Shopping API', 'Application API'],
|
|
124
111
|
consumers: ['Customer Portal'],
|
|
125
112
|
historicVersions: [],
|
|
113
|
+
externalLinks: [],
|
|
126
114
|
owners: ['dboyne', 'mSmith'],
|
|
127
115
|
},
|
|
128
116
|
{
|
|
@@ -131,6 +119,7 @@ describe('events lib', () => {
|
|
|
131
119
|
summary: 'Tells us when an email has been sent\n',
|
|
132
120
|
producers: ['Email Platform'],
|
|
133
121
|
historicVersions: [],
|
|
122
|
+
externalLinks: [],
|
|
134
123
|
consumers: [],
|
|
135
124
|
owners: ['dboyne', 'mSmith'],
|
|
136
125
|
},
|
|
@@ -139,6 +128,7 @@ describe('events lib', () => {
|
|
|
139
128
|
version: '0.0.1',
|
|
140
129
|
summary: 'Example event with schema and examples\n',
|
|
141
130
|
historicVersions: [],
|
|
131
|
+
externalLinks: [],
|
|
142
132
|
producers: [],
|
|
143
133
|
consumers: [],
|
|
144
134
|
owners: [],
|
|
@@ -149,6 +139,7 @@ describe('events lib', () => {
|
|
|
149
139
|
summary: 'Tells us when an email has been sent\n',
|
|
150
140
|
historicVersions: ['0.0.1'],
|
|
151
141
|
producers: [],
|
|
142
|
+
externalLinks: [],
|
|
152
143
|
consumers: [],
|
|
153
144
|
owners: [],
|
|
154
145
|
},
|
|
@@ -206,12 +197,12 @@ describe('events lib', () => {
|
|
|
206
197
|
{
|
|
207
198
|
name: 'AddedItemToCart',
|
|
208
199
|
version: '0.0.1',
|
|
209
|
-
summary:
|
|
210
|
-
'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
200
|
+
summary: 'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
211
201
|
producers: ['Shopping API', 'Application API'],
|
|
212
202
|
consumers: ['Customer Portal'],
|
|
213
|
-
historicVersions: [],
|
|
214
203
|
owners: ['dboyne', 'mSmith'],
|
|
204
|
+
historicVersions: [],
|
|
205
|
+
externalLinks: [],
|
|
215
206
|
},
|
|
216
207
|
{
|
|
217
208
|
name: 'EmailSent',
|
|
@@ -220,6 +211,7 @@ describe('events lib', () => {
|
|
|
220
211
|
producers: ['Email Platform'],
|
|
221
212
|
consumers: [],
|
|
222
213
|
historicVersions: [],
|
|
214
|
+
externalLinks: [],
|
|
223
215
|
owners: ['dboyne', 'mSmith'],
|
|
224
216
|
},
|
|
225
217
|
]);
|
|
@@ -232,8 +224,7 @@ describe('events lib', () => {
|
|
|
232
224
|
{
|
|
233
225
|
name: 'AddedItemToCart',
|
|
234
226
|
version: '0.0.1',
|
|
235
|
-
summary:
|
|
236
|
-
'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
227
|
+
summary: 'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
237
228
|
producers: ['Shopping API', 'My Service'],
|
|
238
229
|
consumers: ['Customer Portal'],
|
|
239
230
|
historicVersions: [],
|
|
@@ -254,8 +245,7 @@ describe('events lib', () => {
|
|
|
254
245
|
{
|
|
255
246
|
name: 'AddedItemToCart',
|
|
256
247
|
version: '0.0.1',
|
|
257
|
-
summary:
|
|
258
|
-
'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
248
|
+
summary: 'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
259
249
|
producers: ['Shopping API', 'My Service'],
|
|
260
250
|
consumers: ['Customer Portal'],
|
|
261
251
|
historicVersions: [],
|
|
@@ -271,8 +261,7 @@ describe('events lib', () => {
|
|
|
271
261
|
{
|
|
272
262
|
name: 'AddedItemToCart',
|
|
273
263
|
version: '0.0.1',
|
|
274
|
-
summary:
|
|
275
|
-
'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
264
|
+
summary: 'Holds information about the cusomer and product when they add an item to the cart.\n',
|
|
276
265
|
producers: ['Shopping API', 'Service'],
|
|
277
266
|
consumers: ['Customer Portal'],
|
|
278
267
|
historicVersions: [],
|
|
@@ -21,9 +21,7 @@ describe('file-reader lib', () => {
|
|
|
21
21
|
{ encoding: 'utf-8' }
|
|
22
22
|
);
|
|
23
23
|
|
|
24
|
-
const result = getSchemaFromDir(
|
|
25
|
-
path.join(process.env.PROJECT_DIR, 'events', 'EventWithSchemaAndExamples')
|
|
26
|
-
);
|
|
24
|
+
const result = getSchemaFromDir(path.join(process.env.PROJECT_DIR, 'events', 'EventWithSchemaAndExamples'));
|
|
27
25
|
|
|
28
26
|
expect(result.snippet).toEqual(rawSchemaFile);
|
|
29
27
|
expect(result.language).toEqual('json');
|
|
@@ -42,14 +40,10 @@ describe('file-reader lib', () => {
|
|
|
42
40
|
path.join(process.env.PROJECT_DIR, 'events', 'EventWithSchemaAndExamples', 'schema.json')
|
|
43
41
|
);
|
|
44
42
|
|
|
45
|
-
const stats = fs.statSync(
|
|
46
|
-
path.join(process.env.PROJECT_DIR, 'events', 'EventWithSchemaAndExamples', 'schema.json')
|
|
47
|
-
);
|
|
43
|
+
const stats = fs.statSync(path.join(process.env.PROJECT_DIR, 'events', 'EventWithSchemaAndExamples', 'schema.json'));
|
|
48
44
|
|
|
49
45
|
const fileData = new Date(stats.mtime);
|
|
50
|
-
const expectedResult = `${fileData.getFullYear()}/${
|
|
51
|
-
fileData.getMonth() + 1
|
|
52
|
-
}/${fileData.getDate()}`;
|
|
46
|
+
const expectedResult = `${fileData.getFullYear()}/${fileData.getMonth() + 1}/${fileData.getDate()}`;
|
|
53
47
|
|
|
54
48
|
expect(result).toEqual(expectedResult);
|
|
55
49
|
});
|
|
@@ -18,10 +18,27 @@ describe('services', () => {
|
|
|
18
18
|
const services = await getAllServices();
|
|
19
19
|
|
|
20
20
|
expect(services).toEqual([
|
|
21
|
+
{
|
|
22
|
+
externalLinks: [
|
|
23
|
+
{
|
|
24
|
+
label: 'AsyncAPI Specification',
|
|
25
|
+
url: 'https://studio.asyncapi.com/#schema-lightMeasuredPayload',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
name: 'Basket Service',
|
|
29
|
+
owners: ['mSmith'],
|
|
30
|
+
publishes: [],
|
|
31
|
+
repository: {
|
|
32
|
+
language: 'JavaScript',
|
|
33
|
+
url: 'https://github.com/boyney123/pretend-basket-service',
|
|
34
|
+
},
|
|
35
|
+
subscribes: [],
|
|
36
|
+
summary: 'CRUD based API to handle Basket interactions for users of the shopping website.\n',
|
|
37
|
+
tags: [],
|
|
38
|
+
},
|
|
21
39
|
{
|
|
22
40
|
name: 'Email Platform',
|
|
23
|
-
summary:
|
|
24
|
-
'Internal Email system. Used to send emails to 1000s of customers. Hosted in AWS\n',
|
|
41
|
+
summary: 'Internal Email system. Used to send emails to 1000s of customers. Hosted in AWS\n',
|
|
25
42
|
owners: ['dboyne'],
|
|
26
43
|
repository: {
|
|
27
44
|
url: 'https://github.com/boyney123/EmailPlatform',
|
|
@@ -43,11 +60,13 @@ describe('services', () => {
|
|
|
43
60
|
summary: 'Tells us when an email has been sent\n',
|
|
44
61
|
producers: ['Email Platform'],
|
|
45
62
|
consumers: [],
|
|
63
|
+
externalLinks: [],
|
|
46
64
|
historicVersions: [],
|
|
47
65
|
owners: ['dboyne', 'mSmith'],
|
|
48
66
|
},
|
|
49
67
|
],
|
|
50
68
|
subscribes: [],
|
|
69
|
+
externalLinks: [],
|
|
51
70
|
},
|
|
52
71
|
]);
|
|
53
72
|
});
|
|
@@ -65,8 +84,7 @@ describe('services', () => {
|
|
|
65
84
|
expect(services).toEqual([
|
|
66
85
|
{
|
|
67
86
|
name: 'Email Platform',
|
|
68
|
-
summary:
|
|
69
|
-
'Internal Email system. Used to send emails to 1000s of customers. Hosted in AWS\n',
|
|
87
|
+
summary: 'Internal Email system. Used to send emails to 1000s of customers. Hosted in AWS\n',
|
|
70
88
|
owners: ['dboyne'],
|
|
71
89
|
repository: {
|
|
72
90
|
url: 'https://github.com/boyney123/EmailPlatform',
|
|
@@ -89,10 +107,12 @@ describe('services', () => {
|
|
|
89
107
|
producers: ['Email Platform'],
|
|
90
108
|
consumers: [],
|
|
91
109
|
historicVersions: [],
|
|
110
|
+
externalLinks: [],
|
|
92
111
|
owners: ['dboyne', 'mSmith'],
|
|
93
112
|
},
|
|
94
113
|
],
|
|
95
114
|
subscribes: [],
|
|
115
|
+
externalLinks: [],
|
|
96
116
|
},
|
|
97
117
|
]);
|
|
98
118
|
});
|
|
@@ -104,8 +124,7 @@ describe('services', () => {
|
|
|
104
124
|
|
|
105
125
|
expect(service).toEqual({
|
|
106
126
|
name: 'Email Platform',
|
|
107
|
-
summary:
|
|
108
|
-
'Internal Email system. Used to send emails to 1000s of customers. Hosted in AWS\n',
|
|
127
|
+
summary: 'Internal Email system. Used to send emails to 1000s of customers. Hosted in AWS\n',
|
|
109
128
|
owners: ['dboyne'],
|
|
110
129
|
repository: {
|
|
111
130
|
url: 'https://github.com/boyney123/EmailPlatform',
|
|
@@ -128,10 +147,12 @@ describe('services', () => {
|
|
|
128
147
|
producers: ['Email Platform'],
|
|
129
148
|
consumers: [],
|
|
130
149
|
historicVersions: [],
|
|
150
|
+
externalLinks: [],
|
|
131
151
|
owners: ['dboyne', 'mSmith'],
|
|
132
152
|
},
|
|
133
153
|
],
|
|
134
154
|
subscribes: [],
|
|
155
|
+
externalLinks: [],
|
|
135
156
|
});
|
|
136
157
|
|
|
137
158
|
// @ts-ignore
|
package/lib/events.ts
CHANGED
|
@@ -11,8 +11,8 @@ import { extentionToLanguageMap } from './file-reader';
|
|
|
11
11
|
import { getLastModifiedDateOfFile, getSchemaFromDir, readMarkdownFile } from '@/lib/file-reader';
|
|
12
12
|
|
|
13
13
|
const parseEventFrontMatterIntoEvent = (eventFrontMatter: any): Event => {
|
|
14
|
-
const { name, version, summary, producers = [], consumers = [], owners = [] } = eventFrontMatter;
|
|
15
|
-
return { name, version, summary, producers, consumers, owners };
|
|
14
|
+
const { name, version, summary, producers = [], consumers = [], owners = [], externalLinks = [] } = eventFrontMatter;
|
|
15
|
+
return { name, version, summary, producers, consumers, owners, externalLinks };
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
const versionsForEvents = (pathToEvent) => {
|
|
@@ -36,9 +36,7 @@ export const getLogsForEvent = (eventName) => {
|
|
|
36
36
|
}));
|
|
37
37
|
|
|
38
38
|
// Get the latest version
|
|
39
|
-
const { data: { version: latestVersion } = {} } = readMarkdownFile(
|
|
40
|
-
path.join(eventsDir, eventName, 'index.md')
|
|
41
|
-
);
|
|
39
|
+
const { data: { version: latestVersion } = {} } = readMarkdownFile(path.join(eventsDir, eventName, 'index.md'));
|
|
42
40
|
|
|
43
41
|
// Add the current version to the list
|
|
44
42
|
allVersions.unshift({ version: latestVersion, pathToDir: path.join(eventsDir, eventName) });
|
|
@@ -143,10 +141,7 @@ export const getAllEvents = (): Event[] => {
|
|
|
143
141
|
});
|
|
144
142
|
};
|
|
145
143
|
|
|
146
|
-
export const getEventByName = async (
|
|
147
|
-
eventName: string,
|
|
148
|
-
version?: string
|
|
149
|
-
): Promise<{ event: Event; markdown: MarkdownFile }> => {
|
|
144
|
+
export const getEventByName = async (eventName: string, version?: string): Promise<{ event: Event; markdown: MarkdownFile }> => {
|
|
150
145
|
const eventsDir = path.join(process.env.PROJECT_DIR, 'events');
|
|
151
146
|
const eventDirectory = path.join(eventsDir, eventName);
|
|
152
147
|
let versionDirectory = null;
|
package/lib/file-reader.ts
CHANGED
|
@@ -46,7 +46,5 @@ export const getSchemaFromDir = (pathToSchemaDir: string): Schema => {
|
|
|
46
46
|
export const getLastModifiedDateOfFile = (filePath) => {
|
|
47
47
|
const stats = fs.statSync(filePath);
|
|
48
48
|
const lastModifiedDate = new Date(stats.mtime);
|
|
49
|
-
return `${lastModifiedDate.getFullYear()}/${
|
|
50
|
-
lastModifiedDate.getMonth() + 1
|
|
51
|
-
}/${lastModifiedDate.getDate()}`;
|
|
49
|
+
return `${lastModifiedDate.getFullYear()}/${lastModifiedDate.getMonth() + 1}/${lastModifiedDate.getDate()}`;
|
|
52
50
|
};
|
package/lib/graphs.ts
CHANGED
|
@@ -16,10 +16,8 @@ ${rNodes.map((node) => `${nodeValue}:::event-->${node}:::consumer\n`).join('')}
|
|
|
16
16
|
`;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
export const buildMermaidFlowChartForEvent = (
|
|
20
|
-
|
|
21
|
-
rootNodeColor = '#2563eb'
|
|
22
|
-
) => buildMermaid(eventName, producers, consumers, rootNodeColor);
|
|
19
|
+
export const buildMermaidFlowChartForEvent = ({ name: eventName, producers, consumers }: Event, rootNodeColor = '#2563eb') =>
|
|
20
|
+
buildMermaid(eventName, producers, consumers, rootNodeColor);
|
|
23
21
|
|
|
24
22
|
export const buildMermaidFlowChartForService = (
|
|
25
23
|
{ publishes, subscribes, name: serviceName }: Service,
|
package/lib/services.ts
CHANGED
|
@@ -8,17 +8,15 @@ import { MarkdownFile } from '../types/index';
|
|
|
8
8
|
import { getAllEvents, getAllEventsThatHaveRelationshipWithService } from '@/lib/events';
|
|
9
9
|
|
|
10
10
|
const buildService = (eventFrontMatter: any): Service => {
|
|
11
|
-
const { name, summary, owners = [], repository = {}, tags = [] } = eventFrontMatter;
|
|
12
|
-
return { name, summary, owners, repository, tags };
|
|
11
|
+
const { name, summary, owners = [], repository = {}, tags = [], externalLinks = [] } = eventFrontMatter;
|
|
12
|
+
return { name, summary, owners, repository, tags, externalLinks };
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export const getAllServices = (): Service[] => {
|
|
16
16
|
const servicesDir = path.join(process.env.PROJECT_DIR, 'services');
|
|
17
17
|
|
|
18
18
|
const folders = fs.readdirSync(servicesDir);
|
|
19
|
-
const services = folders.map((folder) =>
|
|
20
|
-
readMarkdownFile(path.join(servicesDir, folder, 'index.md'))
|
|
21
|
-
);
|
|
19
|
+
const services = folders.map((folder) => readMarkdownFile(path.join(servicesDir, folder, 'index.md')));
|
|
22
20
|
const events = getAllEvents();
|
|
23
21
|
|
|
24
22
|
const parsedServices = services.map((frontMatter) => buildService(frontMatter.data));
|
|
@@ -32,17 +30,13 @@ export const getAllServices = (): Service[] => {
|
|
|
32
30
|
|
|
33
31
|
export const getAllServicesByOwnerId = async (ownerId): Promise<Service[]> => {
|
|
34
32
|
const services = await getAllServices();
|
|
35
|
-
const servicesOwnedByUser = services.filter((service) =>
|
|
36
|
-
service.owners.some((id) => id === ownerId)
|
|
37
|
-
);
|
|
33
|
+
const servicesOwnedByUser = services.filter((service) => service.owners.some((id) => id === ownerId));
|
|
38
34
|
return servicesOwnedByUser.map((service) => ({
|
|
39
35
|
...service,
|
|
40
36
|
}));
|
|
41
37
|
};
|
|
42
38
|
|
|
43
|
-
export const getServiceByName = async (
|
|
44
|
-
serviceName
|
|
45
|
-
): Promise<{ service: Service; markdown: MarkdownFile }> => {
|
|
39
|
+
export const getServiceByName = async (serviceName): Promise<{ service: Service; markdown: MarkdownFile }> => {
|
|
46
40
|
try {
|
|
47
41
|
const servicesDir = path.join(process.env.PROJECT_DIR, 'services');
|
|
48
42
|
const serviceDirectory = path.join(servicesDir, serviceName);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eventcatalog/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"react-syntax-highlighter": "^15.4.5"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@eventcatalog/types": "0.0.
|
|
40
|
+
"@eventcatalog/types": "0.0.3",
|
|
41
41
|
"@types/react": "^17.0.36",
|
|
42
42
|
"autoprefixer": "^10.4.0",
|
|
43
43
|
"commander": "^8.3.0",
|
package/pages/_app.tsx
CHANGED
|
@@ -18,29 +18,20 @@ export default ({ Component, pageProps }: AppProps) => (
|
|
|
18
18
|
/>
|
|
19
19
|
<meta property="og:url" content="https://eventcatalog.dev/" />
|
|
20
20
|
<meta property="og:type" content="website" />
|
|
21
|
-
<meta
|
|
22
|
-
property="og:title"
|
|
23
|
-
content="EventCatalog | Discover, Explore and Document your Event Driven Architectures."
|
|
24
|
-
/>
|
|
21
|
+
<meta property="og:title" content="EventCatalog | Discover, Explore and Document your Event Driven Architectures." />
|
|
25
22
|
<meta
|
|
26
23
|
property="og:description"
|
|
27
24
|
content="An open source tool powered by markdown to document your Event Driven Architecture."
|
|
28
25
|
/>
|
|
29
26
|
<meta property="og:image" content="https://eventcatalog.dev/img/opengraph.png" />
|
|
30
|
-
<meta
|
|
31
|
-
property="og:image:alt"
|
|
32
|
-
content="EventCatalog | Discover, Explore and Document your Event Driven Architectures."
|
|
33
|
-
/>
|
|
27
|
+
<meta property="og:image:alt" content="EventCatalog | Discover, Explore and Document your Event Driven Architectures." />
|
|
34
28
|
<meta property="og:image:width" content="1200" />
|
|
35
29
|
<meta property="og:image:height" content="600" />
|
|
36
30
|
<meta property="og:locale" content="en-GB" />
|
|
37
31
|
<meta name="author" content="David Boyne" />
|
|
38
32
|
|
|
39
33
|
{/* Need to load this before any of the Html2Diff Code */}
|
|
40
|
-
<link
|
|
41
|
-
rel="stylesheet"
|
|
42
|
-
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/atom-one-light.min.css"
|
|
43
|
-
/>
|
|
34
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/atom-one-light.min.css" />
|
|
44
35
|
</Head>
|
|
45
36
|
<Header />
|
|
46
37
|
<Component {...pageProps} />
|
|
@@ -59,17 +59,13 @@ function Logs({ changes, name: eventName, currentVersion }: LogsProps) {
|
|
|
59
59
|
<BreadCrumbs pages={pages} />
|
|
60
60
|
</div>
|
|
61
61
|
<div>
|
|
62
|
-
<div>
|
|
63
|
-
<div className="
|
|
64
|
-
<
|
|
65
|
-
<h1 className="text-3xl font-bold text-gray-900 relative">EmailSent</h1>
|
|
66
|
-
</div>
|
|
62
|
+
<div className="border-b pb-4 flex justify-between mb-4">
|
|
63
|
+
<div className="space-y-2 w-full">
|
|
64
|
+
<h1 className="text-3xl font-bold text-gray-900 relative">{eventName}</h1>
|
|
67
65
|
</div>
|
|
68
66
|
</div>
|
|
69
67
|
|
|
70
|
-
{changes.length === 0 &&
|
|
71
|
-
<div className="text-gray-400 text-xl">No versions for Event found.</div>
|
|
72
|
-
)}
|
|
68
|
+
{changes.length === 0 && <div className="text-gray-400 text-xl">No versions for Event found.</div>}
|
|
73
69
|
|
|
74
70
|
<div className="flow-root mb-20">
|
|
75
71
|
<ul className="">
|
|
@@ -77,10 +73,7 @@ function Logs({ changes, name: eventName, currentVersion }: LogsProps) {
|
|
|
77
73
|
<li key={eventIdx} className="">
|
|
78
74
|
<div className="relative pb-8">
|
|
79
75
|
{eventIdx !== changes.length - 1 ? (
|
|
80
|
-
<span
|
|
81
|
-
className="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-100"
|
|
82
|
-
aria-hidden="true"
|
|
83
|
-
/>
|
|
76
|
+
<span className="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-100" aria-hidden="true" />
|
|
84
77
|
) : null}
|
|
85
78
|
<div className="relative flex space-x-3">
|
|
86
79
|
<div>
|
|
@@ -99,9 +92,7 @@ function Logs({ changes, name: eventName, currentVersion }: LogsProps) {
|
|
|
99
92
|
Schema version update
|
|
100
93
|
{event.versions.map((version, index) => {
|
|
101
94
|
const linkHref =
|
|
102
|
-
version === currentVersion
|
|
103
|
-
? `/events/${eventName}`
|
|
104
|
-
: `/events/${eventName}/v/${version}`;
|
|
95
|
+
version === currentVersion ? `/events/${eventName}` : `/events/${eventName}/v/${version}`;
|
|
105
96
|
return (
|
|
106
97
|
<Link key={version} href={linkHref}>
|
|
107
98
|
<a className="font-medium">
|
|
@@ -127,9 +118,7 @@ function Logs({ changes, name: eventName, currentVersion }: LogsProps) {
|
|
|
127
118
|
</>
|
|
128
119
|
)}
|
|
129
120
|
{!event.changelog.source && (
|
|
130
|
-
<h2 className="text-base text-gray-300 font-bold mt-4">
|
|
131
|
-
No changelog file found.
|
|
132
|
-
</h2>
|
|
121
|
+
<h2 className="text-base text-gray-300 font-bold mt-4">No changelog file found.</h2>
|
|
133
122
|
)}
|
|
134
123
|
</div>
|
|
135
124
|
<div className="text-right text-sm text-gray-500 py-4">
|
package/pages/events/[name].tsx
CHANGED
|
@@ -2,7 +2,6 @@ import Head from 'next/head';
|
|
|
2
2
|
import { MDXRemote } from 'next-mdx-remote';
|
|
3
3
|
|
|
4
4
|
import { Event } from '@eventcatalog/types';
|
|
5
|
-
import { editUrl } from '../../eventcatalog.config';
|
|
6
5
|
import Admonition from '@/components/Mdx/Admonition';
|
|
7
6
|
import Examples from '@/components/Mdx/Examples';
|
|
8
7
|
|
|
@@ -31,11 +30,7 @@ export const getComponents = ({ event, schema, examples }: any) => ({
|
|
|
31
30
|
code: ({ className, ...props }) => {
|
|
32
31
|
const match = /language-(\w+)/.exec(className || '');
|
|
33
32
|
|
|
34
|
-
return match ?
|
|
35
|
-
<SyntaxHighlighter language={match[1]} {...props} />
|
|
36
|
-
) : (
|
|
37
|
-
<code className={className} {...props} />
|
|
38
|
-
);
|
|
33
|
+
return match ? <SyntaxHighlighter language={match[1]} {...props} /> : <code className={className} {...props} />;
|
|
39
34
|
},
|
|
40
35
|
Schema: ({ title = 'Event Schema' }: { title: string }) => {
|
|
41
36
|
if (!schema) return null;
|
|
@@ -45,11 +40,7 @@ export const getComponents = ({ event, schema, examples }: any) => ({
|
|
|
45
40
|
<h2 id="activity-title" className="text-lg font-medium text-gray-900 underline">
|
|
46
41
|
{title}
|
|
47
42
|
</h2>
|
|
48
|
-
<SyntaxHighlighter
|
|
49
|
-
language={schema.language}
|
|
50
|
-
showLineNumbers={false}
|
|
51
|
-
name={`${event.name} Schema (${schema.language})`}
|
|
52
|
-
>
|
|
43
|
+
<SyntaxHighlighter language={schema.language} showLineNumbers={false} name={`${event.name} Schema (${schema.language})`}>
|
|
53
44
|
{schema.snippet}
|
|
54
45
|
</SyntaxHighlighter>
|
|
55
46
|
</section>
|
|
@@ -75,11 +66,13 @@ export const getComponents = ({ event, schema, examples }: any) => ({
|
|
|
75
66
|
|
|
76
67
|
export default function Events(props: EventsPageProps) {
|
|
77
68
|
const { event, markdown, loadedVersion, notFound } = props;
|
|
78
|
-
const { getEditUrl } = useUrl();
|
|
79
|
-
|
|
80
|
-
if (notFound) return <NotFound type="event" name={event.name} editUrl={editUrl} />;
|
|
69
|
+
const { getEditUrl, hasEditUrl } = useUrl();
|
|
81
70
|
|
|
82
71
|
const { name, summary, draft, schema, examples, version } = event;
|
|
72
|
+
|
|
73
|
+
if (notFound)
|
|
74
|
+
return <NotFound type="event" name={event.name} editUrl={hasEditUrl ? getEditUrl(`/events/${name}/index.md`) : ''} />;
|
|
75
|
+
|
|
83
76
|
const { lastModifiedDate } = markdown;
|
|
84
77
|
|
|
85
78
|
const pages = [
|
|
@@ -97,9 +90,8 @@ export default function Events(props: EventsPageProps) {
|
|
|
97
90
|
</title>
|
|
98
91
|
</Head>
|
|
99
92
|
<ContentView
|
|
100
|
-
// {...props}
|
|
101
93
|
title={name}
|
|
102
|
-
editUrl={getEditUrl(`/events/${name}/index.md`)}
|
|
94
|
+
editUrl={hasEditUrl ? getEditUrl(`/events/${name}/index.md`) : ''}
|
|
103
95
|
subtitle={summary}
|
|
104
96
|
draft={draft}
|
|
105
97
|
lastModifiedDate={lastModifiedDate}
|
package/pages/events.tsx
CHANGED
|
@@ -57,12 +57,8 @@ export default function Page({ events, services }: PageProps) {
|
|
|
57
57
|
eventsToRender = eventsToRender.filter((event) => {
|
|
58
58
|
const { services: serviceFilters } = selectedFilters;
|
|
59
59
|
|
|
60
|
-
const hasConsumersFromFilters = event.consumers.some(
|
|
61
|
-
|
|
62
|
-
);
|
|
63
|
-
const hasProducersFromFilters = event.producers.some(
|
|
64
|
-
(producerId) => serviceFilters.indexOf(producerId) > -1
|
|
65
|
-
);
|
|
60
|
+
const hasConsumersFromFilters = event.consumers.some((consumerId) => serviceFilters.indexOf(consumerId) > -1);
|
|
61
|
+
const hasProducersFromFilters = event.producers.some((producerId) => serviceFilters.indexOf(producerId) > -1);
|
|
66
62
|
|
|
67
63
|
return hasConsumersFromFilters || hasProducersFromFilters;
|
|
68
64
|
});
|
|
@@ -75,9 +71,7 @@ export default function Page({ events, services }: PageProps) {
|
|
|
75
71
|
</Head>
|
|
76
72
|
<main className="max-w-7xl mx-auto min-h-screen px-4 md:px-0">
|
|
77
73
|
<div className="relative z-10 flex items-baseline justify-between pt-8 pb-6 border-b border-gray-200">
|
|
78
|
-
<h1 className="text-2xl font-extrabold tracking-tight text-gray-900">
|
|
79
|
-
Events ({events.length})
|
|
80
|
-
</h1>
|
|
74
|
+
<h1 className="text-2xl font-extrabold tracking-tight text-gray-900">Events ({events.length})</h1>
|
|
81
75
|
|
|
82
76
|
<div className="flex items-center">
|
|
83
77
|
<Menu as="div" className="hidden relative text-left">
|
|
@@ -160,10 +154,7 @@ export default function Page({ events, services }: PageProps) {
|
|
|
160
154
|
defaultChecked={option.checked}
|
|
161
155
|
className="h-4 w-4 border-gray-300 rounded text-gray-600 focus:ring-gray-500"
|
|
162
156
|
/>
|
|
163
|
-
<label
|
|
164
|
-
htmlFor={`filter-${section.id}-${optionIdx}`}
|
|
165
|
-
className="ml-3 text-sm text-gray-600"
|
|
166
|
-
>
|
|
157
|
+
<label htmlFor={`filter-${section.id}-${optionIdx}`} className="ml-3 text-sm text-gray-600">
|
|
167
158
|
{option.label}
|
|
168
159
|
</label>
|
|
169
160
|
</div>
|
|
@@ -200,9 +191,7 @@ export default function Page({ events, services }: PageProps) {
|
|
|
200
191
|
|
|
201
192
|
<div className="col-span-4 lg:col-span-3">
|
|
202
193
|
<div>
|
|
203
|
-
<h2 className="text-gray-500 text-xs font-medium uppercase tracking-wide">
|
|
204
|
-
Events ({eventsToRender.length})
|
|
205
|
-
</h2>
|
|
194
|
+
<h2 className="text-gray-500 text-xs font-medium uppercase tracking-wide">Events ({eventsToRender.length})</h2>
|
|
206
195
|
<EventGrid events={eventsToRender} showMermaidDiagrams={showMermaidDiagrams} />
|
|
207
196
|
</div>
|
|
208
197
|
</div>
|
package/pages/index.tsx
CHANGED
|
@@ -11,15 +11,8 @@ export default function Example() {
|
|
|
11
11
|
return (
|
|
12
12
|
<main className="sm:bg-top md:min-h-screen bg-gradient-to-t from-blue-700 to-gray-800">
|
|
13
13
|
<div className="max-w-7xl mx-auto px-4 py-16 text-center sm:px-6 sm:py-24 lg:px-8 lg:py-48">
|
|
14
|
-
<img
|
|
15
|
-
|
|
16
|
-
alt={logoToLoad.alt}
|
|
17
|
-
style={{ height: '85px' }}
|
|
18
|
-
className="mx-auto"
|
|
19
|
-
/>
|
|
20
|
-
<h1 className="mt-2 text-4xl font-extrabold text-white tracking-tight sm:text-5xl">
|
|
21
|
-
{title}
|
|
22
|
-
</h1>
|
|
14
|
+
<img src={logoToLoad.src} alt={logoToLoad.alt} style={{ height: '85px' }} className="mx-auto" />
|
|
15
|
+
<h1 className="mt-2 text-4xl font-extrabold text-white tracking-tight sm:text-5xl">{title}</h1>
|
|
23
16
|
{tagline && <p className="mt-2 text-lg font-medium text-white">{tagline}</p>}
|
|
24
17
|
<div className="mt-5 max-w-md mx-auto sm:flex sm:justify-center md:mt-8">
|
|
25
18
|
<div className="rounded-md shadow">
|
package/pages/overview.tsx
CHANGED
|
@@ -6,10 +6,7 @@ import dynamic from 'next/dynamic';
|
|
|
6
6
|
|
|
7
7
|
import { getAllEvents, getUniqueServicesNamesFromEvents } from '@/lib/events';
|
|
8
8
|
|
|
9
|
-
const ForceGraph3D = dynamic(
|
|
10
|
-
() => import('react-force-graph-3d').then((module) => module.default),
|
|
11
|
-
{ ssr: false }
|
|
12
|
-
);
|
|
9
|
+
const ForceGraph3D = dynamic(() => import('react-force-graph-3d').then((module) => module.default), { ssr: false });
|
|
13
10
|
|
|
14
11
|
function NodeElement({ node: { id } }: { node: { id: string } }) {
|
|
15
12
|
return <div className={`text-sm text-center p-1 rounded-md `}>{id}</div>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Head from 'next/head';
|
|
2
2
|
import { MDXRemote } from 'next-mdx-remote';
|
|
3
3
|
import { Service } from '@eventcatalog/types';
|
|
4
|
-
import { editUrl } from '../../eventcatalog.config.js';
|
|
5
4
|
import ContentView from '@/components/ContentView';
|
|
6
5
|
import { getAllServices, getServiceByName } from '@/lib/services';
|
|
7
6
|
|
|
@@ -37,9 +36,12 @@ const getComponents = (service) => ({
|
|
|
37
36
|
|
|
38
37
|
export default function Services(props: ServicesPageProps) {
|
|
39
38
|
const { service, markdown, notFound } = props;
|
|
40
|
-
const { getEditUrl } = useUrl();
|
|
39
|
+
const { getEditUrl, hasEditUrl } = useUrl();
|
|
41
40
|
|
|
42
|
-
if (notFound)
|
|
41
|
+
if (notFound)
|
|
42
|
+
return (
|
|
43
|
+
<NotFound type="service" name={service.name} editUrl={hasEditUrl ? getEditUrl(`/services/${service.name}/index.md`) : ''} />
|
|
44
|
+
);
|
|
43
45
|
|
|
44
46
|
const { name, summary, draft } = service;
|
|
45
47
|
const { lastModifiedDate } = markdown;
|
|
@@ -58,7 +60,7 @@ export default function Services(props: ServicesPageProps) {
|
|
|
58
60
|
</Head>
|
|
59
61
|
<ContentView
|
|
60
62
|
title={name}
|
|
61
|
-
editUrl={getEditUrl(`/services/${name}/index.md`)}
|
|
63
|
+
editUrl={hasEditUrl ? getEditUrl(`/services/${name}/index.md`) : ''}
|
|
62
64
|
subtitle={summary}
|
|
63
65
|
draft={draft}
|
|
64
66
|
lastModifiedDate={lastModifiedDate}
|
package/pages/services.tsx
CHANGED
|
@@ -31,9 +31,7 @@ export default function Page({ services }: PageProps) {
|
|
|
31
31
|
</Head>
|
|
32
32
|
<main className="max-w-7xl mx-auto md:min-h-screen px-4 md:px-0">
|
|
33
33
|
<div className="relative z-10 flex items-baseline justify-between pt-8 pb-6 border-b border-gray-200">
|
|
34
|
-
<h1 className="text-2xl font-extrabold tracking-tight text-gray-900">
|
|
35
|
-
Services ({services.length})
|
|
36
|
-
</h1>
|
|
34
|
+
<h1 className="text-2xl font-extrabold tracking-tight text-gray-900">Services ({services.length})</h1>
|
|
37
35
|
|
|
38
36
|
<div className="flex items-center">
|
|
39
37
|
<Menu as="div" className="relative hidden text-left">
|
|
@@ -99,9 +97,7 @@ export default function Page({ services }: PageProps) {
|
|
|
99
97
|
|
|
100
98
|
<div className="col-span-4 lg:col-span-3">
|
|
101
99
|
<div>
|
|
102
|
-
<h2 className="text-gray-500 text-xs font-medium uppercase tracking-wide">
|
|
103
|
-
Services
|
|
104
|
-
</h2>
|
|
100
|
+
<h2 className="text-gray-500 text-xs font-medium uppercase tracking-wide">Services</h2>
|
|
105
101
|
<ServiceGrid services={services} />
|
|
106
102
|
</div>
|
|
107
103
|
</div>
|