@eventcatalog/core 2.48.1 → 2.48.3

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.
Files changed (28) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/{chunk-WAVFA46U.js → chunk-6GN2GDPD.js} +1 -1
  6. package/dist/{chunk-M35UFAGG.js → chunk-BPCESQRH.js} +1 -1
  7. package/dist/{chunk-ZI5ZP7I2.js → chunk-UFBO6R65.js} +1 -1
  8. package/dist/constants.cjs +1 -1
  9. package/dist/constants.js +1 -1
  10. package/dist/eventcatalog.cjs +1 -1
  11. package/dist/eventcatalog.config.d.cts +6 -0
  12. package/dist/eventcatalog.config.d.ts +6 -0
  13. package/dist/eventcatalog.js +3 -3
  14. package/eventcatalog/src/components/EnvironmentDropdown.tsx +135 -0
  15. package/eventcatalog/src/components/Header.astro +8 -1
  16. package/eventcatalog/src/components/SideNav/ListViewSideBar/components/MessageList.tsx +1 -0
  17. package/eventcatalog/src/components/SideNav/ListViewSideBar/index.tsx +1 -0
  18. package/eventcatalog/src/components/SideNav/ListViewSideBar/types.ts +1 -0
  19. package/eventcatalog/src/components/SideNav/ListViewSideBar/utils.ts +5 -0
  20. package/eventcatalog/src/components/Tables/Table.tsx +44 -12
  21. package/eventcatalog/src/components/Tables/columns/DomainTableColumns.tsx +5 -1
  22. package/eventcatalog/src/components/Tables/columns/MessageTableColumns.tsx +5 -1
  23. package/eventcatalog/src/components/Tables/columns/ServiceTableColumns.tsx +5 -1
  24. package/eventcatalog/src/content.config.ts +1 -0
  25. package/eventcatalog/src/layouts/DiscoverLayout.astro +15 -3
  26. package/eventcatalog/src/pages/discover/[type]/index.astro +1 -0
  27. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +15 -0
  28. package/package.json +1 -1
@@ -37,7 +37,7 @@ var import_axios = __toESM(require("axios"), 1);
37
37
  var import_os = __toESM(require("os"), 1);
38
38
 
39
39
  // package.json
40
- var version = "2.48.1";
40
+ var version = "2.48.3";
41
41
 
42
42
  // src/constants.ts
43
43
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-M35UFAGG.js";
4
- import "../chunk-WAVFA46U.js";
3
+ } from "../chunk-BPCESQRH.js";
4
+ import "../chunk-6GN2GDPD.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -106,7 +106,7 @@ var import_axios = __toESM(require("axios"), 1);
106
106
  var import_os = __toESM(require("os"), 1);
107
107
 
108
108
  // package.json
109
- var version = "2.48.1";
109
+ var version = "2.48.3";
110
110
 
111
111
  // src/constants.ts
112
112
  var VERSION = version;
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-ZI5ZP7I2.js";
4
- import "../chunk-M35UFAGG.js";
5
- import "../chunk-WAVFA46U.js";
3
+ } from "../chunk-UFBO6R65.js";
4
+ import "../chunk-BPCESQRH.js";
5
+ import "../chunk-6GN2GDPD.js";
6
6
  import "../chunk-E7TXTI7G.js";
7
7
  export {
8
8
  log_build_default as default
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "2.48.1";
2
+ var version = "2.48.3";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-WAVFA46U.js";
3
+ } from "./chunk-6GN2GDPD.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import axios from "axios";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-M35UFAGG.js";
3
+ } from "./chunk-BPCESQRH.js";
4
4
  import {
5
5
  getEventCatalogConfigFile,
6
6
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "2.48.1";
28
+ var version = "2.48.3";
29
29
 
30
30
  // src/constants.ts
31
31
  var VERSION = version;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-WAVFA46U.js";
3
+ } from "./chunk-6GN2GDPD.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -157,7 +157,7 @@ var import_axios = __toESM(require("axios"), 1);
157
157
  var import_os = __toESM(require("os"), 1);
158
158
 
159
159
  // package.json
160
- var version = "2.48.1";
160
+ var version = "2.48.3";
161
161
 
162
162
  // src/constants.ts
163
163
  var VERSION = version;
@@ -101,6 +101,12 @@ interface Config {
101
101
  renderMode?: 'flat' | 'single';
102
102
  };
103
103
  };
104
+ environments?: {
105
+ name: string;
106
+ url: string;
107
+ description?: string;
108
+ shortName?: string;
109
+ }[];
104
110
  }
105
111
 
106
112
  export type { Config, SideBarConfig };
@@ -101,6 +101,12 @@ interface Config {
101
101
  renderMode?: 'flat' | 'single';
102
102
  };
103
103
  };
104
+ environments?: {
105
+ name: string;
106
+ url: string;
107
+ description?: string;
108
+ shortName?: string;
109
+ }[];
104
110
  }
105
111
 
106
112
  export type { Config, SideBarConfig };
@@ -6,8 +6,8 @@ import {
6
6
  } from "./chunk-XE6PFSH5.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-ZI5ZP7I2.js";
10
- import "./chunk-M35UFAGG.js";
9
+ } from "./chunk-UFBO6R65.js";
10
+ import "./chunk-BPCESQRH.js";
11
11
  import {
12
12
  catalogToAstro,
13
13
  checkAndConvertMdToMdx
@@ -15,7 +15,7 @@ import {
15
15
  import "./chunk-LDBRNJIL.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-WAVFA46U.js";
18
+ } from "./chunk-6GN2GDPD.js";
19
19
  import {
20
20
  isAuthEnabled,
21
21
  isBackstagePluginEnabled,
@@ -0,0 +1,135 @@
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+
3
+ interface Environment {
4
+ name: string;
5
+ url: string;
6
+ description?: string;
7
+ shortName?: string;
8
+ }
9
+
10
+ interface EnvironmentDropdownProps {
11
+ environments: Environment[];
12
+ }
13
+
14
+ export const EnvironmentDropdown: React.FC<EnvironmentDropdownProps> = ({ environments }) => {
15
+ const [isOpen, setIsOpen] = useState(false);
16
+ const [currentEnvironment, setCurrentEnvironment] = useState<Environment | null>(null);
17
+ const dropdownRef = useRef<HTMLDivElement>(null);
18
+
19
+ useEffect(() => {
20
+ // Check if current URL matches any environment
21
+ const currentUrl = window.location.origin;
22
+ const matchedEnv = environments.find((env) => {
23
+ // Normalize URLs for comparison
24
+ const envUrl = new URL(env.url).origin;
25
+ return envUrl === currentUrl;
26
+ });
27
+ setCurrentEnvironment(matchedEnv || null);
28
+ }, [environments]);
29
+
30
+ useEffect(() => {
31
+ // Handle click outside
32
+ const handleClickOutside = (event: MouseEvent) => {
33
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
34
+ setIsOpen(false);
35
+ }
36
+ };
37
+
38
+ // Handle escape key
39
+ const handleEscape = (event: KeyboardEvent) => {
40
+ if (event.key === 'Escape') {
41
+ setIsOpen(false);
42
+ }
43
+ };
44
+
45
+ if (isOpen) {
46
+ document.addEventListener('click', handleClickOutside);
47
+ document.addEventListener('keydown', handleEscape);
48
+ }
49
+
50
+ return () => {
51
+ document.removeEventListener('click', handleClickOutside);
52
+ document.removeEventListener('keydown', handleEscape);
53
+ };
54
+ }, [isOpen]);
55
+
56
+ const toggleDropdown = (e: React.MouseEvent) => {
57
+ e.stopPropagation();
58
+ setIsOpen(!isOpen);
59
+ };
60
+
61
+ return (
62
+ <div className="relative" ref={dropdownRef}>
63
+ <button
64
+ type="button"
65
+ onClick={toggleDropdown}
66
+ className="flex items-center space-x-1 text-sm font-medium text-gray-700 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500 rounded-md px-3 py-2"
67
+ aria-expanded={isOpen}
68
+ aria-haspopup="true"
69
+ >
70
+ <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
71
+ <path
72
+ strokeLinecap="round"
73
+ strokeLinejoin="round"
74
+ strokeWidth="2"
75
+ d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
76
+ />
77
+ </svg>
78
+ <span>
79
+ Environments
80
+ {currentEnvironment && (
81
+ <span className="font-normal"> ({currentEnvironment.shortName || currentEnvironment.name})</span>
82
+ )}
83
+ </span>
84
+ <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
85
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 9l-7 7-7-7" />
86
+ </svg>
87
+ </button>
88
+ <div
89
+ className={`${isOpen ? '' : 'hidden'} absolute right-0 mt-2 w-64 bg-white rounded-md shadow-lg py-1 z-50 border border-gray-100 overflow-hidden z-20`}
90
+ >
91
+ {environments.map((env) => {
92
+ const isCurrentEnv = currentEnvironment?.name === env.name;
93
+
94
+ return (
95
+ <a
96
+ key={env.name}
97
+ href={env.url}
98
+ onClick={(e) => {
99
+ e.preventDefault();
100
+ // Construct the full URL with the current path when clicked
101
+ const currentPath = window.location.pathname + window.location.search + window.location.hash;
102
+ const targetUrl = new URL(env.url);
103
+ targetUrl.pathname = currentPath;
104
+ window.location.href = targetUrl.toString();
105
+ }}
106
+ className={`block px-4 py-3 text-sm transition-colors border-b border-gray-50 last:border-b-0 ${
107
+ isCurrentEnv ? 'bg-purple-50 text-purple-700 hover:bg-purple-100' : 'text-gray-700 hover:bg-gray-50'
108
+ }`}
109
+ >
110
+ <div className="flex items-center justify-between">
111
+ <div>
112
+ <div className={`font-medium ${isCurrentEnv ? 'text-purple-700' : ''}`}>{env.name}</div>
113
+ {env.description && (
114
+ <div className={`text-xs font-light mt-1 ${isCurrentEnv ? 'text-purple-600' : 'text-gray-500'}`}>
115
+ {env.description}
116
+ </div>
117
+ )}
118
+ </div>
119
+ {isCurrentEnv && (
120
+ <svg className="w-4 h-4 text-purple-600 flex-shrink-0 ml-2" fill="currentColor" viewBox="0 0 20 20">
121
+ <path
122
+ fillRule="evenodd"
123
+ d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
124
+ clipRule="evenodd"
125
+ />
126
+ </svg>
127
+ )}
128
+ </div>
129
+ </a>
130
+ );
131
+ })}
132
+ </div>
133
+ </div>
134
+ );
135
+ };
@@ -5,6 +5,7 @@ import { buildUrl } from '@utils/url-builder';
5
5
  import { showEventCatalogBranding, showCustomBranding } from '@utils/feature';
6
6
  import { getSession } from 'auth-astro/server';
7
7
  import { isAuthEnabled, isSSR } from '@utils/feature';
8
+ import { EnvironmentDropdown } from './EnvironmentDropdown';
8
9
 
9
10
  let session = null;
10
11
  if (isAuthEnabled()) {
@@ -41,7 +42,10 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
41
42
  <div class="hidden md:block w-3/12">
42
43
  {
43
44
  session ? (
44
- <div class="flex justify-end pr-2">
45
+ <div class="flex items-center space-x-4 justify-end pr-2">
46
+ {catalog.environments && catalog.environments.length > 0 && (
47
+ <EnvironmentDropdown environments={catalog.environments} client:load />
48
+ )}
45
49
  <div class="relative">
46
50
  <button
47
51
  id="profile-menu-button"
@@ -89,6 +93,9 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
89
93
  ) : (
90
94
  <>
91
95
  <div class="flex items-center space-x-4 justify-end pr-2">
96
+ {catalog.environments && catalog.environments.length > 0 && (
97
+ <EnvironmentDropdown environments={catalog.environments} client:load />
98
+ )}
92
99
  {isAuthEnabled() && (
93
100
  <button
94
101
  id="okta-signin-btn"
@@ -61,6 +61,7 @@ const MessageList: React.FC<MessageListProps> = ({ messages, decodedCurrentPath,
61
61
  >
62
62
  <span className="truncate">
63
63
  <HighlightedText text={message.data?.sidebar?.label || message.data.name} searchTerm={searchTerm} />
64
+ <span className="text-xs text-gray-400">{message.data.draft ? ' (DRAFT)' : ''}</span>
64
65
  </span>
65
66
  <span
66
67
  className={`ml-2 text-[10px] flex items-center gap-1 font-medium px-2 uppercase py-0.5 rounded ${getMessageColorByLabelOrCollection(message.collection, message.data?.sidebar?.badge)}`}
@@ -91,6 +91,7 @@ const ServiceItem = React.memo(
91
91
  >
92
92
  <span className="truncate text-xs font-bold">
93
93
  <HighlightedText text={item.label} searchTerm={searchTerm} />
94
+ <span className="text-xs text-gray-400">{item.draft ? ' (DRAFT)' : ''}</span>
94
95
  </span>
95
96
  <span className="text-purple-600 ml-2 text-[10px] font-medium bg-purple-50 px-2 py-0.5 rounded">SERVICE</span>
96
97
  </button>
@@ -24,6 +24,7 @@ export interface ServiceItem {
24
24
  name: string;
25
25
  id: string;
26
26
  version: string;
27
+ draft: boolean | { title?: string; message: string };
27
28
  sends: MessageItem[];
28
29
  receives: MessageItem[];
29
30
  entities: EntityItem[];
@@ -59,6 +59,7 @@ export async function getResourcesForNavigation({ currentPath }: { currentPath:
59
59
  name: send.data.name,
60
60
  sidebar: send.data.sidebar,
61
61
  aggregateRoot: send?.data?.aggregateRoot,
62
+ draft: send.data.draft,
62
63
  },
63
64
  collection: send.collection,
64
65
  href: buildUrl(`/${route}/${send.collection}/${send.data.id}/${send.data.version}`),
@@ -69,6 +70,7 @@ export async function getResourcesForNavigation({ currentPath }: { currentPath:
69
70
  name: receive.data.name,
70
71
  sidebar: receive.data.sidebar,
71
72
  aggregateRoot: receive?.data?.aggregateRoot,
73
+ draft: receive.data.draft,
72
74
  },
73
75
  collection: receive.collection,
74
76
  href: buildUrl(`/${route}/${receive.collection}/${receive.data.id}/${receive.data.version}`),
@@ -79,6 +81,7 @@ export async function getResourcesForNavigation({ currentPath }: { currentPath:
79
81
  name: entity.data.name,
80
82
  sidebar: entity.data.sidebar,
81
83
  aggregateRoot: entity?.data?.aggregateRoot,
84
+ draft: entity.data.draft,
82
85
  },
83
86
  collection: entity.collection,
84
87
  href: buildUrl(`/${route}/${entity.collection}/${entity.data.id}/${entity.data.version}`),
@@ -103,6 +106,7 @@ export async function getResourcesForNavigation({ currentPath }: { currentPath:
103
106
  servicesCount,
104
107
  id: item.data.id,
105
108
  name: item.data.name,
109
+ draft: item.data.draft,
106
110
  services: isCollectionDomain ? stripCollection(item.data.services) : null,
107
111
  domains: isCollectionDomain ? stripCollection(item.data.domains) : null,
108
112
  sends: sendsWithHref,
@@ -127,6 +131,7 @@ export async function getResourcesForNavigation({ currentPath }: { currentPath:
127
131
  version: item.data.version,
128
132
  id: item.data.id,
129
133
  name: item.data.name,
134
+ draft: item.data.draft,
130
135
  href: buildUrl(`/${route}/${item.collection}/${item.data.id}/${item.data.version}`),
131
136
  collection: item.collection,
132
137
  }));
@@ -48,6 +48,7 @@ export type TData<T extends TCollectionTypes> = {
48
48
  summary: string;
49
49
  version: string;
50
50
  latestVersion?: string; // Defined on getter collection utility
51
+ draft?: boolean | { title?: string; message: string }; // Draft property from base schema
51
52
  badges?: Array<{
52
53
  id: string; // Where is it defined?
53
54
  content: string;
@@ -124,13 +125,14 @@ export const Table = <T extends TCollectionTypes>({
124
125
  collection,
125
126
  mode = 'simple',
126
127
  checkboxLatestId,
128
+ checkboxDraftsId,
127
129
  }: {
128
130
  data: TData<T>[];
129
131
  collection: T;
130
132
  checkboxLatestId: string;
133
+ checkboxDraftsId: string;
131
134
  mode?: 'simple' | 'full';
132
135
  }) => {
133
- const [data, _setData] = useState(initialData);
134
136
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
135
137
 
136
138
  useEffect(() => {
@@ -142,11 +144,13 @@ export const Table = <T extends TCollectionTypes>({
142
144
  }, []);
143
145
 
144
146
  const [showOnlyLatest, setShowOnlyLatest] = useState(true);
147
+ const [onlyShowDrafts, setOnlyShowDrafts] = useState(false);
145
148
 
146
149
  useEffect(() => {
147
150
  const checkbox = document.getElementById(checkboxLatestId);
148
151
  function handleChange(evt: Event) {
149
- setShowOnlyLatest((evt.target as HTMLInputElement).checked);
152
+ const checked = (evt.target as HTMLInputElement).checked;
153
+ setShowOnlyLatest(checked);
150
154
  }
151
155
 
152
156
  checkbox?.addEventListener('change', handleChange);
@@ -154,10 +158,47 @@ export const Table = <T extends TCollectionTypes>({
154
158
  return () => checkbox?.removeEventListener('change', handleChange);
155
159
  }, [checkboxLatestId]);
156
160
 
161
+ useEffect(() => {
162
+ const checkbox = document.getElementById(checkboxDraftsId);
163
+ function handleChange(evt: Event) {
164
+ const checked = (evt.target as HTMLInputElement).checked;
165
+ setOnlyShowDrafts(checked);
166
+ }
167
+
168
+ checkbox?.addEventListener('change', handleChange);
169
+
170
+ return () => checkbox?.removeEventListener('change', handleChange);
171
+ }, [checkboxDraftsId]);
172
+
173
+ // Filter data based on checkbox states
174
+ const filteredData = useMemo(() => {
175
+ return initialData.filter((row) => {
176
+ // Check if item is a draft
177
+ const isDraft = row.data.draft === true || (typeof row.data.draft === 'object' && row.data.draft !== null);
178
+
179
+ // If "Only show drafts" is enabled, show only drafts
180
+ if (onlyShowDrafts && !isDraft) {
181
+ return false;
182
+ }
183
+
184
+ // If "Only show drafts" is enabled, don't apply other filters
185
+ if (onlyShowDrafts) {
186
+ return true;
187
+ }
188
+
189
+ // Check latest version filter (only when not showing only drafts)
190
+ if (showOnlyLatest) {
191
+ return isSameVersion(row.data.version, row.data.latestVersion);
192
+ }
193
+
194
+ return true;
195
+ });
196
+ }, [initialData, showOnlyLatest, onlyShowDrafts]);
197
+
157
198
  const columns = useMemo(() => getColumnsByCollection(collection), [collection]);
158
199
 
159
200
  const table = useReactTable({
160
- data,
201
+ data: filteredData,
161
202
  columns,
162
203
  onColumnFiltersChange: setColumnFilters,
163
204
  getCoreRowModel: getCoreRowModel(),
@@ -168,15 +209,6 @@ export const Table = <T extends TCollectionTypes>({
168
209
  getPaginationRowModel: getPaginationRowModel(),
169
210
  state: {
170
211
  columnFilters,
171
- globalFilter: showOnlyLatest,
172
- },
173
- onGlobalFilterChange: setShowOnlyLatest,
174
- globalFilterFn: (row, _columnId, showOnlyLatest: boolean) => {
175
- if (showOnlyLatest) {
176
- return isSameVersion(row.original.data.version, row.original.data.latestVersion);
177
- }
178
-
179
- return true;
180
212
  },
181
213
  });
182
214
 
@@ -43,7 +43,11 @@ export const columns = () => [
43
43
  columnHelper.accessor('data.summary', {
44
44
  id: 'summary',
45
45
  header: () => 'Summary',
46
- cell: (info) => <span className="font-light ">{info.renderValue()}</span>,
46
+ cell: (info) => (
47
+ <span className="font-light ">
48
+ {info.renderValue()} {info.row.original.data.draft ? ' (Draft)' : ''}
49
+ </span>
50
+ ),
47
51
  footer: (info) => info.column.id,
48
52
  meta: {
49
53
  showFilter: false,
@@ -60,7 +60,11 @@ export const columns = () => [
60
60
  columnHelper.accessor('data.summary', {
61
61
  id: 'summary',
62
62
  header: () => 'Summary',
63
- cell: (info) => <span className="font-light ">{info.renderValue()}</span>,
63
+ cell: (info) => (
64
+ <span className="font-light ">
65
+ {info.renderValue()} {info.row.original.data.draft ? ' (Draft)' : ''}
66
+ </span>
67
+ ),
64
68
  footer: (info) => info.column.id,
65
69
  meta: {
66
70
  showFilter: false,
@@ -44,7 +44,11 @@ export const columns = () => [
44
44
  columnHelper.accessor('data.summary', {
45
45
  id: 'summary',
46
46
  header: () => 'Summary',
47
- cell: (info) => <span className="font-light ">{info.renderValue()}</span>,
47
+ cell: (info) => (
48
+ <span className="font-light ">
49
+ {info.renderValue()} {info.row.original.data.draft ? ' (Draft)' : ''}
50
+ </span>
51
+ ),
48
52
  footer: (info) => info.column.id,
49
53
  meta: {
50
54
  showFilter: false,
@@ -73,6 +73,7 @@ const baseSchema = z.object({
73
73
  name: z.string(),
74
74
  summary: z.string().optional(),
75
75
  version: z.string(),
76
+ draft: z.union([z.boolean(), z.object({ title: z.string().optional(), message: z.string() })]).optional(),
76
77
  badges: z.array(badge).optional(),
77
78
  owners: z.array(ownerReference).optional(),
78
79
  schemaPath: z.string().optional(),
@@ -31,6 +31,7 @@ const { title, subtitle, data, type } = Astro.props;
31
31
  const currentPath = Astro.url.pathname;
32
32
 
33
33
  const checkboxLatestId = 'latest-only';
34
+ const checkboxDraftsId = 'show-drafts';
34
35
 
35
36
  const tabs = [
36
37
  {
@@ -117,14 +118,25 @@ const tabs = [
117
118
  <h1 class="text-4xl font-semibold text-gray-900 capitalize">{title}</h1>
118
119
  <p class="text-md text-gray-700">{subtitle}</p>
119
120
  </div>
120
- <div class="p-4 border border-gray-200 rounded-md">
121
- <Checkbox id={checkboxLatestId} name={checkboxLatestId} label="Show latest version only" checked />
121
+ <div class="flex gap-4">
122
+ <div class="p-4 border border-gray-200 rounded-md">
123
+ <Checkbox id={checkboxLatestId} name={checkboxLatestId} label="Show latest version only" checked />
124
+ </div>
125
+ <div class="p-4 border border-gray-200 rounded-md">
126
+ <Checkbox id={checkboxDraftsId} name={checkboxDraftsId} label="Show drafts only" />
127
+ </div>
122
128
  </div>
123
129
  </div>
124
130
  <div class="mt-4 flow-root">
125
131
  <div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
126
132
  <div class="inline-block min-w-full align-middle sm:px-6 lg:px-8">
127
- <Table checkboxLatestId={checkboxLatestId} data={data} collection={type} client:load />
133
+ <Table
134
+ checkboxLatestId={checkboxLatestId}
135
+ checkboxDraftsId={checkboxDraftsId}
136
+ data={data}
137
+ collection={type}
138
+ client:load
139
+ />
128
140
  </div>
129
141
  </div>
130
142
  </div>
@@ -34,6 +34,7 @@ function mapToItem(i: any) {
34
34
  summary: d.data?.summary,
35
35
  version: d.data.version,
36
36
  latestVersion: d.data?.latestVersion,
37
+ draft: d.data?.draft,
37
38
  badges: d.data?.badges,
38
39
  // @ts-ignore
39
40
  consumers: d.data?.consumers?.map(mapToItem) ?? [],
@@ -278,6 +278,21 @@ nodeGraphs.push({
278
278
  </div>
279
279
  )
280
280
  }
281
+
282
+ {
283
+ props.data.draft && (
284
+ <Admonition type="warning" title={props.data?.draft?.title || `Draft ${friendlyCollectionName}`}>
285
+ <div>
286
+ {!props.data.draft.message && (
287
+ <p>This resource has been marked as a draft and may still be under development.</p>
288
+ )}
289
+ {props.data.draft.message && (
290
+ <div class="prose prose-sm max-w-none" set:html={marked.parse(props.data.draft.message)} />
291
+ )}
292
+ </div>
293
+ </Admonition>
294
+ )
295
+ }
281
296
  </div>
282
297
  </div>
283
298
 
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/event-catalog/eventcatalog.git"
7
7
  },
8
8
  "type": "module",
9
- "version": "2.48.1",
9
+ "version": "2.48.3",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },