@trebired/git-host 1.4.0 → 1.7.0

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 (91) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +398 -23
  3. package/dist/api/forge/handler.d.ts.map +1 -1
  4. package/dist/api/forge/handler.js +80 -1
  5. package/dist/api/forge/handler.js.map +1 -1
  6. package/dist/api/handler/action.js +1 -1
  7. package/dist/api/handler/action.js.map +1 -1
  8. package/dist/api/handler/archive.d.ts +14 -0
  9. package/dist/api/handler/archive.d.ts.map +1 -0
  10. package/dist/api/handler/archive.js +61 -0
  11. package/dist/api/handler/archive.js.map +1 -0
  12. package/dist/api/handler/response.d.ts.map +1 -1
  13. package/dist/api/handler/response.js +8 -0
  14. package/dist/api/handler/response.js.map +1 -1
  15. package/dist/api/handler/route.d.ts +11 -0
  16. package/dist/api/handler/route.d.ts.map +1 -1
  17. package/dist/api/handler/route.js +10 -0
  18. package/dist/api/handler/route.js.map +1 -1
  19. package/dist/api/handler.d.ts.map +1 -1
  20. package/dist/api/handler.js +29 -1
  21. package/dist/api/handler.js.map +1 -1
  22. package/dist/browser/index.d.ts +36 -15
  23. package/dist/browser/index.d.ts.map +1 -1
  24. package/dist/browser/index.js +622 -592
  25. package/dist/browser/index.js.map +1 -1
  26. package/dist/browser/styles.css +75 -0
  27. package/dist/core/archive.d.ts +25 -0
  28. package/dist/core/archive.d.ts.map +1 -0
  29. package/dist/core/archive.js +419 -0
  30. package/dist/core/archive.js.map +1 -0
  31. package/dist/core/archive_cache_filesystem.d.ts +8 -0
  32. package/dist/core/archive_cache_filesystem.d.ts.map +1 -0
  33. package/dist/core/archive_cache_filesystem.js +158 -0
  34. package/dist/core/archive_cache_filesystem.js.map +1 -0
  35. package/dist/core/create_git_host/content_methods.d.ts +1 -1
  36. package/dist/core/create_git_host/content_methods.d.ts.map +1 -1
  37. package/dist/core/create_git_host/content_methods.js +14 -3
  38. package/dist/core/create_git_host/content_methods.js.map +1 -1
  39. package/dist/core/create_git_host/shared.d.ts +2 -0
  40. package/dist/core/create_git_host/shared.d.ts.map +1 -1
  41. package/dist/core/create_git_host/shared.js.map +1 -1
  42. package/dist/core/create_git_host.d.ts.map +1 -1
  43. package/dist/core/create_git_host.js +7 -0
  44. package/dist/core/create_git_host.js.map +1 -1
  45. package/dist/core/inspect.d.ts +1 -1
  46. package/dist/core/inspect.d.ts.map +1 -1
  47. package/dist/core/inspect.js +11 -26
  48. package/dist/core/inspect.js.map +1 -1
  49. package/dist/errors.d.ts +1 -1
  50. package/dist/errors.d.ts.map +1 -1
  51. package/dist/errors.js.map +1 -1
  52. package/dist/index.d.ts +2 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +1 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/react/client/types.d.ts +5 -2
  57. package/dist/react/client/types.d.ts.map +1 -1
  58. package/dist/react/client.d.ts.map +1 -1
  59. package/dist/react/client.js +14 -0
  60. package/dist/react/client.js.map +1 -1
  61. package/dist/react/components.d.ts +44412 -0
  62. package/dist/react/components.d.ts.map +1 -0
  63. package/dist/react/components.js +758 -0
  64. package/dist/react/components.js.map +1 -0
  65. package/dist/react/hooks/query.d.ts.map +1 -1
  66. package/dist/react/hooks/query.js +30 -5
  67. package/dist/react/hooks/query.js.map +1 -1
  68. package/dist/react/hooks/resources.d.ts.map +1 -1
  69. package/dist/react/hooks/resources.js +1 -1
  70. package/dist/react/hooks/resources.js.map +1 -1
  71. package/dist/react/hooks/types.d.ts +1 -1
  72. package/dist/react/hooks/types.d.ts.map +1 -1
  73. package/dist/react/index.d.ts +3 -0
  74. package/dist/react/index.d.ts.map +1 -1
  75. package/dist/react/index.js +2 -0
  76. package/dist/react/index.js.map +1 -1
  77. package/dist/react/ui/context.d.ts +1907 -0
  78. package/dist/react/ui/context.d.ts.map +1 -0
  79. package/dist/react/ui/context.js +186 -0
  80. package/dist/react/ui/context.js.map +1 -0
  81. package/dist/types/forge.d.ts +2 -1
  82. package/dist/types/forge.d.ts.map +1 -1
  83. package/dist/types/host.d.ts +51 -2
  84. package/dist/types/host.d.ts.map +1 -1
  85. package/dist/types/index.d.ts +2 -2
  86. package/dist/types/index.d.ts.map +1 -1
  87. package/dist/types/repository.d.ts +30 -7
  88. package/dist/types/repository.d.ts.map +1 -1
  89. package/dist/types/transports.d.ts +2 -1
  90. package/dist/types/transports.d.ts.map +1 -1
  91. package/package.json +1 -1
@@ -1,19 +1,43 @@
1
- import { createElement, useDeferredValue, useEffect, useState, } from "react";
1
+ import { createElement, useDeferredValue, useState, } from "react";
2
2
  import { createGitApiClient } from "../react/client.js";
3
- import { GitApiClientProvider, applyGitStarOptimisticState, applyGitWatchOptimisticState, useGitActivity, useGitBlob, useGitCommit, useGitCommits, useGitCreateFork, useGitCreateRelease, useGitForks, useGitOverview, useGitRelease, useGitReleases, useGitSocialState, useGitStarRepository, useGitSyncFork, useGitTree, useGitUnstarRepository, useGitUnwatchRepository, useGitWatchRepository, } from "../react/index.js";
3
+ import { GitActivityList, GitApiClientProvider, GitBlameView, GitBlobView, GitBranchList, GitBranchSelector, GitCommitList, GitCopyCloneUrlButton, GitDeleteReleaseButton, GitDiffView, GitDownloadArchiveButton, GitEditReleaseButton, GitForkButton, GitForkList, GitPathBreadcrumbs, GitReleaseList, GitRepositoryActionBar, GitRepositoryShell, GitRepositorySocialButtons, GitRepositoryUiProvider, GitSearchResults, GitTagList, GitTagSelector, GitTreeView, useGitActivity, useGitBlame, useGitBlob, useGitBranches, useGitCommit, useGitCommits, useGitDiff, useGitForks, useGitCreateRelease, useGitOverview, useGitRelease, useGitReleases, useGitSearch, useGitTags, useGitTree, useGitUpdateRelease, } from "../react/index.js";
4
4
  import { text } from "../utils/text.js";
5
5
  const h = createElement;
6
6
  function joinClassNames(...values) {
7
7
  return values.filter(Boolean).join(" ");
8
8
  }
9
+ function findReadme(entries) {
10
+ const match = entries.find((entry) => entry.type === "blob" && /^readme(\.|$)/i.test(entry.name));
11
+ return match ? match.path : "";
12
+ }
13
+ function createClient(options) {
14
+ return options.client || createGitApiClient({
15
+ baseUrl: text(options.baseUrl),
16
+ headers: options.headers,
17
+ });
18
+ }
19
+ function resolveTheme(theme, unstyled) {
20
+ if (!unstyled)
21
+ return theme;
22
+ return {
23
+ ...(theme || {}),
24
+ unstyled: true,
25
+ };
26
+ }
9
27
  function GitBrowserProvider(props) {
10
- const [client] = useState(() => props.client || createGitApiClient({
11
- baseUrl: text(props.baseUrl),
12
- headers: props.headers,
13
- }));
28
+ const [client] = useState(() => createClient(props));
14
29
  return h(GitApiClientProvider, {
15
30
  client,
16
- children: props.children,
31
+ children: h(GitRepositoryUiProvider, {
32
+ branding: props.branding,
33
+ client,
34
+ diagnostics: props.diagnostics,
35
+ navigate: props.navigate,
36
+ policy: props.policy,
37
+ routeAdapter: props.routeAdapter,
38
+ theme: resolveTheme(props.theme, props.unstyled),
39
+ children: props.children,
40
+ }),
17
41
  });
18
42
  }
19
43
  function withBrowserProvider(props, render) {
@@ -21,206 +45,186 @@ function withBrowserProvider(props, render) {
21
45
  return render();
22
46
  return h(GitBrowserProvider, {
23
47
  baseUrl: props.baseUrl,
48
+ branding: props.branding,
24
49
  client: props.client,
50
+ diagnostics: props.diagnostics,
25
51
  headers: props.headers,
52
+ navigate: props.navigate,
53
+ policy: props.policy,
54
+ routeAdapter: props.routeAdapter,
55
+ theme: resolveTheme(props.theme, props.unstyled),
56
+ unstyled: props.unstyled,
26
57
  children: render(),
27
58
  });
28
59
  }
29
- function formatDate(value) {
30
- const next = text(value);
31
- if (!next)
32
- return "Unknown";
33
- try {
34
- return new Date(next).toLocaleString("en-US", {
35
- dateStyle: "medium",
36
- timeStyle: "short",
37
- });
38
- }
39
- catch {
40
- return next;
41
- }
42
- }
43
- function LinkButton(props) {
44
- return h("button", {
45
- className: joinClassNames("git-browser-nav-link", props.active && "is-active"),
46
- onClick: () => props.navigate && props.navigate(props.to),
47
- type: "button",
48
- children: props.children,
49
- });
50
- }
51
- function StatusBlock(props) {
52
- if (props.loading)
53
- return h("div", { className: "git-browser-status", children: "Loading repository data..." });
54
- if (props.error)
55
- return h("div", { className: "git-browser-status is-error", children: props.error.message });
56
- return h("div", { children: props.children });
57
- }
58
- function RepositoryNav(props) {
59
- return h("div", {
60
- className: "git-browser-nav",
60
+ function overviewStats(overview) {
61
+ if (!overview)
62
+ return [];
63
+ return [
64
+ { label: "Branch", value: overview.repository.repository.current_branch },
65
+ { label: "Head", value: overview.repository.repository.head_short },
66
+ { label: "Stars", value: String(overview.social.star_count) },
67
+ { label: "Watchers", value: String(overview.social.watcher_count) },
68
+ { label: "Releases", value: String(overview.release_count) },
69
+ { label: "Forks", value: String(overview.fork_count) },
70
+ ];
71
+ }
72
+ function defaultSubtitle(repositoryKey, overview) {
73
+ if (!overview)
74
+ return `Repository workspace for ${repositoryKey}`;
75
+ return `${overview.repository.repository.current_branch} branch · ${overview.release_count} releases · ${overview.fork_count} forks`;
76
+ }
77
+ function defaultActionBar(repositoryKey, headers) {
78
+ return h(GitRepositoryActionBar, {
61
79
  children: [
62
- h(LinkButton, { active: props.current === "overview", key: "overview", navigate: props.navigate, to: `/repositories/${props.repositoryKey}/overview`, children: "Overview" }),
63
- h(LinkButton, { active: props.current === "code", key: "code", navigate: props.navigate, to: `/repositories/${props.repositoryKey}/code`, children: "Code" }),
64
- h(LinkButton, { active: props.current === "commits", key: "commits", navigate: props.navigate, to: `/repositories/${props.repositoryKey}/commits`, children: "Commits" }),
65
- h(LinkButton, { active: props.current === "releases", key: "releases", navigate: props.navigate, to: `/repositories/${props.repositoryKey}/releases`, children: "Releases" }),
66
- h(LinkButton, { active: props.current === "forks", key: "forks", navigate: props.navigate, to: `/repositories/${props.repositoryKey}/forks`, children: "Forks" }),
67
- h(LinkButton, { active: props.current === "activity", key: "activity", navigate: props.navigate, to: `/repositories/${props.repositoryKey}/activity`, children: "Activity" }),
80
+ h(GitRepositorySocialButtons, { headers, key: "social", repositoryKey }),
81
+ h(GitForkButton, { headers, key: "fork", repositoryKey }),
82
+ h(GitCopyCloneUrlButton, { key: "clone", repositoryKey }),
83
+ h(GitDownloadArchiveButton, { format: "zip", key: "archive-zip", repositoryKey }),
84
+ h(GitDownloadArchiveButton, { format: "tar.gz", key: "archive-tar", repositoryKey }),
68
85
  ],
69
86
  });
70
87
  }
71
- function SocialControls(props) {
72
- const [optimistic, setOptimistic] = useState(props.social);
73
- useEffect(() => {
74
- setOptimistic(props.social);
75
- }, [props.social]);
76
- const star = useGitStarRepository(props.repositoryKey, { headers: props.headers });
77
- const unstar = useGitUnstarRepository(props.repositoryKey, { headers: props.headers });
78
- const watch = useGitWatchRepository(props.repositoryKey, { headers: props.headers });
79
- const unwatch = useGitUnwatchRepository(props.repositoryKey, { headers: props.headers });
80
- const social = optimistic;
81
- return h("div", {
82
- className: "git-browser-actions",
88
+ function GitReleaseComposerCard(props) {
89
+ const createRelease = useGitCreateRelease(props.repositoryKey, { headers: props.headers });
90
+ const [title, setTitle] = useState("");
91
+ const [tagName, setTagName] = useState("");
92
+ const [notes, setNotes] = useState("");
93
+ return h("section", {
94
+ className: "git-browser-card",
83
95
  children: [
84
- h("button", {
85
- className: joinClassNames("git-browser-action-button", social?.viewer_has_starred && "is-active"),
86
- disabled: star.loading || unstar.loading,
87
- key: "star",
88
- onClick: async () => {
89
- const next = social?.viewer_has_starred !== true;
90
- setOptimistic(applyGitStarOptimisticState(social, next));
91
- try {
92
- setOptimistic(next ? await star.mutate() : await unstar.mutate());
93
- }
94
- catch {
95
- setOptimistic(props.social);
96
- }
96
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Publish a Release" }) }),
97
+ h("form", {
98
+ className: "git-browser-form",
99
+ key: "form",
100
+ onSubmit: async (event) => {
101
+ event.preventDefault();
102
+ await createRelease.mutate({
103
+ createTag: {
104
+ annotatedMessage: notes || title,
105
+ name: tagName,
106
+ targetRef: "HEAD",
107
+ },
108
+ notes,
109
+ title,
110
+ });
111
+ setTitle("");
112
+ setTagName("");
113
+ setNotes("");
114
+ props.onCreated?.();
97
115
  },
98
- type: "button",
99
- children: `${social?.viewer_has_starred ? "Starred" : "Star"} ${social?.star_count ?? 0}`,
100
- }),
101
- h("button", {
102
- className: joinClassNames("git-browser-action-button", social?.viewer_is_watching && "is-active"),
103
- disabled: watch.loading || unwatch.loading,
104
- key: "watch",
105
- onClick: async () => {
106
- const next = social?.viewer_is_watching !== true;
107
- setOptimistic(applyGitWatchOptimisticState(social, next));
108
- try {
109
- setOptimistic(next ? await watch.mutate() : await unwatch.mutate());
110
- }
111
- catch {
112
- setOptimistic(props.social);
113
- }
114
- },
115
- type: "button",
116
- children: `${social?.viewer_is_watching ? "Watching" : "Watch"} ${social?.watcher_count ?? 0}`,
116
+ children: [
117
+ h("input", {
118
+ className: "git-browser-input",
119
+ key: "title",
120
+ onChange: (event) => setTitle(text(event.target?.value)),
121
+ placeholder: "Release title",
122
+ value: title,
123
+ }),
124
+ h("input", {
125
+ className: "git-browser-input",
126
+ key: "tag",
127
+ onChange: (event) => setTagName(text(event.target?.value)),
128
+ placeholder: "Tag name",
129
+ value: tagName,
130
+ }),
131
+ h("textarea", {
132
+ className: "git-browser-input git-browser-textarea",
133
+ key: "notes",
134
+ onChange: (event) => setNotes(text(event.target?.value)),
135
+ placeholder: "Release notes",
136
+ value: notes,
137
+ }),
138
+ h("button", {
139
+ className: "git-browser-action-button is-primary",
140
+ disabled: createRelease.loading || !title || !tagName,
141
+ key: "submit",
142
+ type: "submit",
143
+ children: createRelease.loading ? "Publishing..." : "Publish Release",
144
+ }),
145
+ ],
117
146
  }),
118
147
  ],
119
148
  });
120
149
  }
121
- function RepositoryHeader(props) {
122
- const socialQuery = useGitSocialState(props.repositoryKey, {
123
- headers: props.headers,
124
- initialData: props.overview?.social || null,
125
- });
126
- const createFork = useGitCreateFork(props.repositoryKey, { headers: props.headers });
150
+ function GitReleaseEditorCard(props) {
151
+ const updateRelease = useGitUpdateRelease(props.repositoryKey, text(props.release?.id), { headers: props.headers });
152
+ const [editing, setEditing] = useState(false);
153
+ const [title, setTitle] = useState(text(props.release?.title));
154
+ const [notes, setNotes] = useState(text(props.release?.notes));
155
+ if (!props.release)
156
+ return null;
127
157
  return h("section", {
128
- className: "git-browser-hero",
158
+ className: "git-browser-card",
129
159
  children: [
130
160
  h("div", {
131
- className: "git-browser-hero-top",
132
- key: "title",
161
+ className: "git-browser-card-header",
162
+ key: "header",
133
163
  children: [
164
+ h("h2", { className: "git-browser-card-title", key: "title", children: "Release Actions" }),
134
165
  h("div", {
135
- className: "git-browser-title-block",
136
- key: "block",
137
- children: [
138
- h("div", { className: "git-browser-badge", key: "badge", children: "Embeddable Forge" }),
139
- h("h1", { className: "git-browser-title", key: "title", children: props.repositoryKey }),
140
- h("p", {
141
- className: "git-browser-subtitle",
142
- key: "subtitle",
143
- children: props.overview
144
- ? `${props.overview.repository.repository.current_branch} branch, ${props.overview.release_count} releases, ${props.overview.fork_count} forks`
145
- : "Repository browser",
146
- }),
147
- ],
148
- }),
149
- h("div", {
150
- className: "git-browser-header-actions",
166
+ className: "git-browser-actions",
151
167
  key: "actions",
152
168
  children: [
153
- h(SocialControls, {
169
+ h(GitEditReleaseButton, {
170
+ key: "edit",
171
+ onClick: () => setEditing((current) => !current),
172
+ }),
173
+ h(GitDeleteReleaseButton, {
154
174
  headers: props.headers,
155
- key: "social",
175
+ key: "delete",
176
+ onDeleted: props.onDeleted,
177
+ releaseId: props.release.id,
156
178
  repositoryKey: props.repositoryKey,
157
- social: socialQuery.data,
158
- }),
159
- h("button", {
160
- className: "git-browser-action-button is-primary",
161
- disabled: createFork.loading,
162
- key: "fork",
163
- onClick: async () => {
164
- await createFork.mutate();
165
- },
166
- type: "button",
167
- children: createFork.loading ? "Forking..." : "Create Fork",
168
179
  }),
169
180
  ],
170
181
  }),
171
182
  ],
172
183
  }),
173
- h(RepositoryNav, {
174
- current: props.current,
175
- navigate: props.navigate,
176
- repositoryKey: props.repositoryKey,
177
- key: "nav",
178
- }),
179
- ],
180
- });
181
- }
182
- function Card(props) {
183
- return h("section", {
184
- className: joinClassNames("git-browser-card", props.className),
185
- children: [
186
- h("div", {
187
- className: "git-browser-card-header",
188
- key: "header",
189
- children: [
190
- h("h2", { className: "git-browser-card-title", key: "title", children: props.title }),
191
- props.subtitle ? h("div", { className: "git-browser-card-subtitle", key: "subtitle", children: props.subtitle }) : null,
192
- ],
193
- }),
194
- h("div", {
195
- className: "git-browser-card-body",
196
- key: "body",
197
- children: props.children,
198
- }),
184
+ editing
185
+ ? h("div", {
186
+ className: "git-browser-form",
187
+ key: "editor",
188
+ children: [
189
+ h("input", {
190
+ className: "git-browser-input",
191
+ key: "title",
192
+ onChange: (event) => setTitle(text(event.target?.value)),
193
+ value: title,
194
+ }),
195
+ h("textarea", {
196
+ className: "git-browser-input git-browser-textarea",
197
+ key: "notes",
198
+ onChange: (event) => setNotes(text(event.target?.value)),
199
+ value: notes,
200
+ }),
201
+ h("button", {
202
+ className: "git-browser-action-button is-primary",
203
+ disabled: updateRelease.loading,
204
+ key: "save",
205
+ onClick: async () => {
206
+ await updateRelease.mutate({ notes, title });
207
+ setEditing(false);
208
+ props.onUpdated?.();
209
+ },
210
+ type: "button",
211
+ children: updateRelease.loading ? "Saving..." : "Save Release",
212
+ }),
213
+ ],
214
+ })
215
+ : h("p", { className: "git-browser-note", key: "summary", children: "Toggle edit mode to rename or rewrite release notes." }),
199
216
  ],
200
217
  });
201
218
  }
202
- function DefinitionGrid(props) {
203
- return h("dl", {
204
- className: "git-browser-definition-grid",
205
- children: props.rows.flatMap((row) => ([
206
- h("dt", { key: `${row.label}:label`, children: row.label }),
207
- h("dd", { key: `${row.label}:value`, children: row.value }),
208
- ])),
209
- });
210
- }
211
- function findReadme(entries) {
212
- const match = entries.find((entry) => entry.type === "blob" && /^readme(\.|$)/i.test(entry.name));
213
- return match ? match.path : "";
214
- }
215
219
  function GitRepositoryOverviewPageInner(props) {
216
220
  const overview = useGitOverview(props.repositoryKey, {
217
221
  headers: props.headers,
218
- initialData: props.initialData || null,
222
+ initialData: props.initialData?.overview || null,
219
223
  });
220
224
  const tree = useGitTree(props.repositoryKey, {
225
+ enabled: Boolean(overview.data),
221
226
  headers: props.headers,
222
227
  icons: true,
223
- path: "",
224
228
  recursive: true,
225
229
  ref: overview.data?.repository.repository.current_branch || "HEAD",
226
230
  });
@@ -231,512 +235,523 @@ function GitRepositoryOverviewPageInner(props) {
231
235
  path: readmePath,
232
236
  ref: overview.data?.repository.repository.current_branch || "HEAD",
233
237
  });
234
- return h("div", {
235
- className: joinClassNames("git-browser-page", props.className),
236
- children: [
237
- h(RepositoryHeader, {
238
- current: "overview",
239
- headers: props.headers,
240
- key: "header",
241
- navigate: props.navigate,
242
- overview: overview.data,
243
- repositoryKey: props.repositoryKey,
244
- }),
245
- h(StatusBlock, {
246
- error: overview.error,
247
- key: "status",
248
- loading: overview.loading,
249
- children: overview.data ? h("div", {
250
- className: "git-browser-grid",
238
+ return h(GitRepositoryShell, {
239
+ actions: defaultActionBar(props.repositoryKey, props.headers),
240
+ className: props.className,
241
+ error: overview.error,
242
+ loading: overview.loading,
243
+ page: "overview",
244
+ repositoryKey: props.repositoryKey,
245
+ social: overview.data?.social,
246
+ stats: overviewStats(overview.data),
247
+ subtitle: defaultSubtitle(props.repositoryKey, overview.data),
248
+ children: h("div", {
249
+ className: "git-browser-grid",
250
+ children: [
251
+ h("section", {
252
+ className: "git-browser-card git-browser-span-2",
253
+ key: "summary",
251
254
  children: [
252
- h(Card, {
253
- className: "git-browser-span-2",
254
- key: "summary",
255
- title: "Repository Summary",
256
- subtitle: overview.data.repository.repository.path,
257
- children: h(DefinitionGrid, {
258
- rows: [
259
- { label: "Branch", value: overview.data.repository.repository.current_branch },
260
- { label: "Head", value: overview.data.repository.repository.head_short },
261
- { label: "Releases", value: String(overview.data.release_count) },
262
- { label: "Forks", value: String(overview.data.fork_count) },
263
- { label: "Activity", value: String(overview.data.activity_count) },
264
- ],
265
- }),
266
- }),
267
- h(Card, {
268
- key: "latest-release",
269
- title: "Latest Release",
270
- children: overview.data.latest_release
271
- ? [
272
- h("div", { className: "git-browser-inline-meta", key: "title", children: `${overview.data.latest_release.title} · ${overview.data.latest_release.tag_name}` }),
273
- h("p", { className: "git-browser-note", key: "notes", children: overview.data.latest_release.notes || "No notes yet." }),
274
- ]
275
- : "No releases published yet.",
276
- }),
277
- h(Card, {
278
- className: "git-browser-span-3",
279
- key: "readme",
280
- title: "README",
281
- children: readme.data
282
- ? h("pre", { className: "git-browser-code-block", children: readme.data.content })
283
- : "README content not available.",
284
- }),
255
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Repository Summary" }) }),
256
+ h("p", { className: "git-browser-note", key: "path", children: overview.data?.repository.repository.path || "" }),
285
257
  ],
286
- }) : null,
287
- }),
288
- ],
258
+ }),
259
+ h("section", {
260
+ className: "git-browser-card",
261
+ key: "latest-release",
262
+ children: [
263
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Latest Release" }) }),
264
+ overview.data?.latest_release
265
+ ? h(GitReleaseList, { key: "list", releases: [overview.data.latest_release], repositoryKey: props.repositoryKey })
266
+ : h("p", { className: "git-browser-note", key: "empty", children: "No releases published yet." }),
267
+ ],
268
+ }),
269
+ h("section", {
270
+ className: "git-browser-card git-browser-span-3",
271
+ key: "readme",
272
+ children: [
273
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "README" }) }),
274
+ h(GitBlobView, { content: readme.data?.content, key: "blob", path: readmePath || "README" }),
275
+ ],
276
+ }),
277
+ ],
278
+ }),
289
279
  });
290
280
  }
291
281
  function GitRepositoryCodePageInner(props) {
292
282
  const overview = useGitOverview(props.repositoryKey, {
293
283
  headers: props.headers,
294
- initialData: props.initialData || null,
284
+ initialData: props.initialData?.overview || null,
295
285
  });
296
- const deferredPath = useDeferredValue(text(props.path));
286
+ const [selectedPath, setSelectedPath] = useState(text(props.path));
287
+ const deferredPath = useDeferredValue(selectedPath);
288
+ const refName = props.refName || overview.data?.repository.repository.current_branch || "HEAD";
297
289
  const tree = useGitTree(props.repositoryKey, {
298
290
  headers: props.headers,
299
291
  icons: true,
300
292
  linguist: true,
301
293
  recursive: true,
302
- ref: props.refName || overview.data?.repository.repository.current_branch || "HEAD",
294
+ ref: refName,
303
295
  });
304
- const selectedPath = deferredPath || (tree.data || []).find((entry) => entry.type === "blob")?.path || "";
305
- const selectedEntry = (tree.data || []).find((entry) => entry.path === selectedPath) || null;
296
+ const resolvedPath = deferredPath || (tree.data || []).find((entry) => entry.type === "blob")?.path || "";
297
+ const selectedEntry = (tree.data || []).find((entry) => entry.path === resolvedPath) || null;
306
298
  const blob = useGitBlob(props.repositoryKey, {
307
299
  enabled: Boolean(selectedEntry && selectedEntry.type === "blob"),
308
300
  headers: props.headers,
309
- path: selectedPath,
310
- ref: props.refName || overview.data?.repository.repository.current_branch || "HEAD",
311
- });
312
- return h("div", {
313
- className: joinClassNames("git-browser-page", props.className),
314
- children: [
315
- h(RepositoryHeader, {
316
- current: "code",
317
- headers: props.headers,
318
- key: "header",
319
- navigate: props.navigate,
320
- overview: overview.data,
321
- repositoryKey: props.repositoryKey,
322
- }),
323
- h(StatusBlock, {
324
- error: tree.error || blob.error,
325
- key: "status",
326
- loading: overview.loading || tree.loading || blob.loading,
327
- children: h("div", {
328
- className: "git-browser-split",
301
+ path: resolvedPath,
302
+ ref: refName,
303
+ });
304
+ return h(GitRepositoryShell, {
305
+ actions: h(GitRepositoryActionBar, {
306
+ children: [
307
+ h(GitBranchSelector, { headers: props.headers, key: "branch", repositoryKey: props.repositoryKey, selectedBranch: overview.data?.repository.repository.current_branch }),
308
+ h(GitTagSelector, { headers: props.headers, key: "tag", repositoryKey: props.repositoryKey }),
309
+ ],
310
+ }),
311
+ className: props.className,
312
+ error: tree.error || blob.error,
313
+ loading: overview.loading || tree.loading,
314
+ page: "code",
315
+ repositoryKey: props.repositoryKey,
316
+ social: overview.data?.social,
317
+ stats: overviewStats(overview.data),
318
+ subtitle: defaultSubtitle(props.repositoryKey, overview.data),
319
+ children: h("div", {
320
+ className: "git-browser-split",
321
+ children: [
322
+ h("section", {
323
+ className: "git-browser-card",
324
+ key: "tree",
329
325
  children: [
330
- h(Card, {
331
- key: "tree",
332
- title: "Repository Tree",
333
- subtitle: props.refName || overview.data?.repository.repository.current_branch || "HEAD",
334
- children: h("ul", {
335
- className: "git-browser-list",
336
- children: (tree.data || []).map((entry) => (h("li", {
337
- className: joinClassNames("git-browser-list-item", entry.path === selectedPath && "is-selected"),
338
- key: entry.path,
339
- children: `${entry.type === "tree" ? "dir" : "file"} · ${entry.path}${entry.language ? ` · ${entry.language}` : ""}`,
340
- }))),
341
- }),
326
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Repository Tree" }) }),
327
+ h(GitTreeView, {
328
+ entries: tree.data || [],
329
+ key: "body",
330
+ onSelectPath: setSelectedPath,
331
+ selectedPath: resolvedPath,
342
332
  }),
343
- h(Card, {
344
- className: "git-browser-span-2",
345
- key: "blob",
346
- title: selectedPath || "File Preview",
333
+ ],
334
+ }),
335
+ h("div", {
336
+ className: "git-browser-grid",
337
+ key: "blob",
338
+ children: [
339
+ h(GitPathBreadcrumbs, { key: "crumbs", path: resolvedPath, refName, repositoryKey: props.repositoryKey }),
340
+ h(GitBlobView, {
341
+ content: blob.data?.content,
342
+ key: "view",
343
+ path: resolvedPath,
347
344
  subtitle: selectedEntry?.language || "Plain text",
348
- children: blob.data
349
- ? h("pre", { className: "git-browser-code-block", children: blob.data.content })
350
- : "Select a file path to preview blob content.",
351
345
  }),
352
346
  ],
353
347
  }),
354
- }),
355
- ],
348
+ ],
349
+ }),
356
350
  });
357
351
  }
358
352
  function GitRepositoryCommitsPageInner(props) {
359
353
  const overview = useGitOverview(props.repositoryKey, {
360
354
  headers: props.headers,
361
- initialData: props.initialData || null,
355
+ initialData: props.initialData?.overview || null,
362
356
  });
357
+ const [limit, setLimit] = useState(20);
363
358
  const commits = useGitCommits(props.repositoryKey, {
364
359
  headers: props.headers,
360
+ initialData: props.initialData?.commits || null,
361
+ limit,
365
362
  path: props.path,
366
363
  ref: props.refName || overview.data?.repository.repository.current_branch || "HEAD",
367
364
  });
368
- return h("div", {
369
- className: joinClassNames("git-browser-page", props.className),
370
- children: [
371
- h(RepositoryHeader, {
372
- current: "commits",
373
- headers: props.headers,
374
- key: "header",
375
- navigate: props.navigate,
376
- overview: overview.data,
377
- repositoryKey: props.repositoryKey,
378
- }),
379
- h(StatusBlock, {
380
- error: commits.error,
381
- key: "status",
382
- loading: overview.loading || commits.loading,
383
- children: h(Card, {
384
- title: "Commit History",
385
- subtitle: props.path ? `Filtered to ${props.path}` : "Latest repository activity",
386
- children: h("ul", {
387
- className: "git-browser-list",
388
- children: (commits.data || []).map((commit) => (h("li", {
389
- className: "git-browser-list-item",
390
- key: commit.hash,
391
- children: `${commit.short_hash} · ${commit.subject} · ${commit.author_name} · ${formatDate(commit.authored_at)}`,
392
- }))),
393
- }),
394
- }),
395
- }),
396
- ],
365
+ return h(GitRepositoryShell, {
366
+ actions: h(GitRepositoryActionBar, {
367
+ children: h(GitBranchSelector, { headers: props.headers, repositoryKey: props.repositoryKey, selectedBranch: overview.data?.repository.repository.current_branch }),
368
+ }),
369
+ className: props.className,
370
+ error: commits.error,
371
+ loading: overview.loading || commits.loading,
372
+ page: "commits",
373
+ repositoryKey: props.repositoryKey,
374
+ social: overview.data?.social,
375
+ stats: overviewStats(overview.data),
376
+ subtitle: props.path ? `History filtered to ${props.path}` : defaultSubtitle(props.repositoryKey, overview.data),
377
+ children: h("section", {
378
+ className: "git-browser-card",
379
+ children: [
380
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Commit History" }) }),
381
+ h(GitCommitList, { commits: commits.data || [], key: "list", repositoryKey: props.repositoryKey }),
382
+ (commits.data || []).length >= limit
383
+ ? h("button", {
384
+ className: "git-browser-action-button",
385
+ key: "more",
386
+ onClick: () => setLimit((current) => current + 20),
387
+ type: "button",
388
+ children: "Load More Commits",
389
+ })
390
+ : null,
391
+ ],
392
+ }),
397
393
  });
398
394
  }
399
395
  function GitRepositoryCommitPageInner(props) {
400
396
  const overview = useGitOverview(props.repositoryKey, {
401
397
  headers: props.headers,
402
- initialData: props.initialData || null,
398
+ initialData: props.initialData?.overview || null,
403
399
  });
404
400
  const commit = useGitCommit(props.repositoryKey, props.commitRef, {
405
401
  headers: props.headers,
406
- });
407
- return h("div", {
408
- className: joinClassNames("git-browser-page", props.className),
409
- children: [
410
- h(RepositoryHeader, {
411
- current: "commits",
412
- headers: props.headers,
413
- key: "header",
414
- navigate: props.navigate,
415
- overview: overview.data,
416
- repositoryKey: props.repositoryKey,
417
- }),
418
- h(StatusBlock, {
419
- error: commit.error,
420
- key: "status",
421
- loading: overview.loading || commit.loading,
422
- children: commit.data ? h("div", {
423
- className: "git-browser-grid",
402
+ initialData: props.initialData?.commit || null,
403
+ });
404
+ return h(GitRepositoryShell, {
405
+ className: props.className,
406
+ error: commit.error,
407
+ loading: overview.loading || commit.loading,
408
+ page: "commit",
409
+ repositoryKey: props.repositoryKey,
410
+ social: overview.data?.social,
411
+ stats: overviewStats(overview.data),
412
+ subtitle: defaultSubtitle(props.repositoryKey, overview.data),
413
+ children: commit.data ? h("div", {
414
+ className: "git-browser-grid",
415
+ children: [
416
+ h("section", {
417
+ className: "git-browser-card git-browser-span-3",
418
+ key: "meta",
424
419
  children: [
425
- h(Card, {
426
- className: "git-browser-span-3",
427
- key: "meta",
428
- title: commit.data.commit.subject,
429
- subtitle: `${commit.data.commit.short_hash} by ${commit.data.commit.author_name}`,
430
- children: h(DefinitionGrid, {
431
- rows: [
432
- { label: "Authored", value: formatDate(commit.data.commit.authored_at) },
433
- { label: "Files", value: String(commit.data.file_count) },
434
- { label: "Added", value: String(commit.data.lines_added) },
435
- { label: "Removed", value: String(commit.data.lines_removed) },
436
- ],
437
- }),
438
- }),
439
- h(Card, {
440
- className: "git-browser-span-3",
441
- key: "diff",
442
- title: "Diff",
443
- children: h("pre", { className: "git-browser-code-block", children: commit.data.diff }),
444
- }),
420
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: commit.data.commit.subject }) }),
421
+ h("p", { className: "git-browser-note", key: "meta", children: `${commit.data.commit.short_hash} · ${commit.data.commit.author_name} · ${commit.data.file_count} files` }),
422
+ h("pre", { className: "git-browser-code-block", key: "diff", children: commit.data.diff }),
445
423
  ],
446
- }) : null,
447
- }),
448
- ],
449
- });
450
- }
451
- function ReleaseComposer(props) {
452
- const createRelease = useGitCreateRelease(props.repositoryKey, { headers: props.headers });
453
- const [title, setTitle] = useState("");
454
- const [tagName, setTagName] = useState("");
455
- const [notes, setNotes] = useState("");
456
- return h("form", {
457
- className: "git-browser-form",
458
- onSubmit: async (event) => {
459
- event.preventDefault();
460
- const release = await createRelease.mutate({
461
- createTag: {
462
- annotatedMessage: notes || title,
463
- name: tagName,
464
- targetRef: "HEAD",
465
- },
466
- notes,
467
- title,
468
- });
469
- setTitle("");
470
- setTagName("");
471
- setNotes("");
472
- props.onCreated(release);
473
- },
474
- children: [
475
- h("input", {
476
- className: "git-browser-input",
477
- key: "title",
478
- onChange: (event) => setTitle(text(event.target?.value)),
479
- placeholder: "Release title",
480
- value: title,
481
- }),
482
- h("input", {
483
- className: "git-browser-input",
484
- key: "tag",
485
- onChange: (event) => setTagName(text(event.target?.value)),
486
- placeholder: "Tag name",
487
- value: tagName,
488
- }),
489
- h("textarea", {
490
- className: "git-browser-input git-browser-textarea",
491
- key: "notes",
492
- onChange: (event) => setNotes(text(event.target?.value)),
493
- placeholder: "Release notes",
494
- value: notes,
495
- }),
496
- h("button", {
497
- className: "git-browser-action-button is-primary",
498
- disabled: createRelease.loading || !title || !tagName,
499
- key: "submit",
500
- type: "submit",
501
- children: createRelease.loading ? "Publishing..." : "Publish Release",
502
- }),
503
- ],
424
+ }),
425
+ ],
426
+ }) : null,
504
427
  });
505
428
  }
506
429
  function GitRepositoryReleasesPageInner(props) {
507
430
  const overview = useGitOverview(props.repositoryKey, {
508
431
  headers: props.headers,
509
- initialData: props.initialData || null,
432
+ initialData: props.initialData?.overview || null,
510
433
  });
511
434
  const releases = useGitReleases(props.repositoryKey, {
512
435
  headers: props.headers,
513
- });
514
- const [createdRelease, setCreatedRelease] = useState(null);
515
- useEffect(() => {
516
- if (createdRelease)
517
- releases.reload();
518
- }, [createdRelease]);
519
- return h("div", {
520
- className: joinClassNames("git-browser-page", props.className),
521
- children: [
522
- h(RepositoryHeader, {
523
- current: "releases",
524
- headers: props.headers,
525
- key: "header",
526
- navigate: props.navigate,
527
- overview: overview.data,
528
- repositoryKey: props.repositoryKey,
529
- }),
530
- h(StatusBlock, {
531
- error: releases.error,
532
- key: "status",
533
- loading: overview.loading || releases.loading,
534
- children: h("div", {
535
- className: "git-browser-grid",
436
+ initialData: props.initialData?.releases || null,
437
+ });
438
+ return h(GitRepositoryShell, {
439
+ actions: defaultActionBar(props.repositoryKey, props.headers),
440
+ className: props.className,
441
+ error: releases.error,
442
+ loading: overview.loading || releases.loading,
443
+ page: "releases",
444
+ repositoryKey: props.repositoryKey,
445
+ social: overview.data?.social,
446
+ stats: overviewStats(overview.data),
447
+ subtitle: defaultSubtitle(props.repositoryKey, overview.data),
448
+ children: h("div", {
449
+ className: "git-browser-grid",
450
+ children: [
451
+ h(GitReleaseComposerCard, {
452
+ headers: props.headers,
453
+ key: "composer",
454
+ onCreated: releases.reload,
455
+ repositoryKey: props.repositoryKey,
456
+ }),
457
+ h("section", {
458
+ className: "git-browser-card git-browser-span-2",
459
+ key: "list-card",
536
460
  children: [
537
- h(Card, {
538
- key: "composer",
539
- title: "Publish a Release",
540
- subtitle: "This creates an annotated tag when needed.",
541
- children: h(ReleaseComposer, {
542
- headers: props.headers,
543
- onCreated: setCreatedRelease,
544
- repositoryKey: props.repositoryKey,
545
- }),
546
- }),
547
- h(Card, {
548
- className: "git-browser-span-2",
549
- key: "list",
550
- title: "Releases",
551
- children: h("ul", {
552
- className: "git-browser-list",
553
- children: (releases.data || []).map((release) => (h("li", {
554
- className: "git-browser-list-item",
555
- key: release.id,
556
- children: [
557
- h("strong", { key: "title", children: `${release.title} · ${release.tag_name}` }),
558
- h("div", { className: "git-browser-note", key: "meta", children: `${release.prerelease ? "Prerelease" : "Stable"} · ${formatDate(release.published_at || release.created_at)}` }),
559
- h("p", { className: "git-browser-note", key: "notes", children: release.notes || "No release notes." }),
560
- ],
561
- }))),
562
- }),
563
- }),
461
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Releases" }) }),
462
+ h(GitReleaseList, { key: "list", releases: releases.data || [], repositoryKey: props.repositoryKey }),
564
463
  ],
565
464
  }),
566
- }),
567
- ],
465
+ ],
466
+ }),
568
467
  });
569
468
  }
570
469
  function GitRepositoryReleasePageInner(props) {
571
470
  const overview = useGitOverview(props.repositoryKey, {
572
471
  headers: props.headers,
573
- initialData: props.initialData || null,
472
+ initialData: props.initialData?.overview || null,
574
473
  });
575
474
  const release = useGitRelease(props.repositoryKey, props.releaseId, {
576
475
  headers: props.headers,
577
- });
578
- return h("div", {
579
- className: joinClassNames("git-browser-page", props.className),
580
- children: [
581
- h(RepositoryHeader, {
582
- current: "releases",
583
- headers: props.headers,
584
- key: "header",
585
- navigate: props.navigate,
586
- overview: overview.data,
587
- repositoryKey: props.repositoryKey,
588
- }),
589
- h(StatusBlock, {
590
- error: release.error,
591
- key: "status",
592
- loading: overview.loading || release.loading,
593
- children: release.data ? h("div", {
594
- className: "git-browser-grid",
476
+ initialData: props.initialData?.release || null,
477
+ });
478
+ return h(GitRepositoryShell, {
479
+ actions: defaultActionBar(props.repositoryKey, props.headers),
480
+ className: props.className,
481
+ error: release.error,
482
+ loading: overview.loading || release.loading,
483
+ page: "release",
484
+ repositoryKey: props.repositoryKey,
485
+ social: overview.data?.social,
486
+ stats: overviewStats(overview.data),
487
+ subtitle: defaultSubtitle(props.repositoryKey, overview.data),
488
+ children: release.data ? h("div", {
489
+ className: "git-browser-grid",
490
+ children: [
491
+ h("section", {
492
+ className: "git-browser-card git-browser-span-2",
493
+ key: "details",
595
494
  children: [
596
- h(Card, {
597
- className: "git-browser-span-2",
598
- key: "details",
599
- title: release.data.title,
600
- subtitle: `${release.data.tag_name} · ${release.data.prerelease ? "Prerelease" : "Release"}`,
601
- children: [
602
- h("p", { className: "git-browser-note", key: "notes", children: release.data.notes || "No release notes." }),
603
- h(DefinitionGrid, {
604
- key: "meta",
605
- rows: [
606
- { label: "Published", value: formatDate(release.data.published_at || release.data.created_at) },
607
- { label: "Target", value: release.data.target_ref },
608
- { label: "Assets", value: String(release.data.assets.length) },
609
- ],
610
- }),
611
- ],
612
- }),
613
- h(Card, {
614
- key: "assets",
615
- title: "Assets",
616
- children: release.data.assets.length
617
- ? h("ul", {
618
- className: "git-browser-list",
619
- children: release.data.assets.map((asset) => (h("li", {
620
- className: "git-browser-list-item",
621
- key: asset.id,
622
- children: `${asset.name}${asset.size ? ` · ${asset.size} bytes` : ""}`,
623
- }))),
624
- })
625
- : "No assets attached.",
626
- }),
495
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: `${release.data.title} · ${release.data.tag_name}` }) }),
496
+ h("p", { className: "git-browser-note", key: "notes", children: release.data.notes || "No release notes." }),
627
497
  ],
628
- }) : null,
629
- }),
630
- ],
631
- });
632
- }
633
- function ForkRow(props) {
634
- const syncFork = useGitSyncFork(props.repositoryKey, props.fork.fork_repository_id, { headers: props.headers });
635
- const [currentFork, setCurrentFork] = useState(props.fork);
636
- useEffect(() => {
637
- setCurrentFork(props.fork);
638
- }, [props.fork]);
639
- return h("li", {
640
- className: "git-browser-list-item",
641
- children: [
642
- h("strong", { key: "name", children: currentFork.fork_repository_id }),
643
- h("div", {
644
- className: "git-browser-note",
645
- key: "status",
646
- children: `Ahead ${currentFork.fork_status.ahead} · Behind ${currentFork.fork_status.behind} · ${currentFork.fork_status.fork_branch} vs ${currentFork.fork_status.upstream_branch}`,
647
- }),
648
- h("button", {
649
- className: "git-browser-action-button",
650
- disabled: syncFork.loading,
651
- key: "sync",
652
- onClick: async () => {
653
- setCurrentFork(await syncFork.mutate({ strategy: "ff-only" }));
654
- },
655
- type: "button",
656
- children: syncFork.loading ? "Syncing..." : "Sync Fork",
657
- }),
658
- ],
498
+ }),
499
+ h("section", {
500
+ className: "git-browser-card",
501
+ key: "source-archives",
502
+ children: [
503
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Source Code" }) }),
504
+ release.data.source_archives
505
+ ? h(GitRepositoryActionBar, {
506
+ key: "links",
507
+ children: [
508
+ h("a", { className: "git-browser-button", href: release.data.source_archives.zip.href, key: "zip", children: "Source code (zip)" }),
509
+ h("a", { className: "git-browser-button", href: release.data.source_archives.tar_gz.href, key: "tar", children: "Source code (tar.gz)" }),
510
+ ],
511
+ })
512
+ : h("p", { className: "git-browser-note", key: "empty", children: "Source archives are unavailable for this release tag." }),
513
+ ],
514
+ }),
515
+ h("section", {
516
+ className: "git-browser-card",
517
+ key: "assets",
518
+ children: [
519
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Assets" }) }),
520
+ release.data.assets.length
521
+ ? h("ul", {
522
+ className: "git-browser-list",
523
+ key: "list",
524
+ children: release.data.assets.map((asset) => h("li", {
525
+ className: "git-browser-list-item",
526
+ key: asset.id,
527
+ children: `${asset.name}${asset.size ? ` · ${asset.size} bytes` : ""}`,
528
+ })),
529
+ })
530
+ : h("p", { className: "git-browser-note", key: "empty", children: "No uploaded release assets." }),
531
+ ],
532
+ }),
533
+ h(GitReleaseEditorCard, {
534
+ headers: props.headers,
535
+ key: "editor",
536
+ onDeleted: release.reload,
537
+ onUpdated: release.reload,
538
+ release: release.data,
539
+ repositoryKey: props.repositoryKey,
540
+ }),
541
+ ],
542
+ }) : null,
659
543
  });
660
544
  }
661
545
  function GitRepositoryForksPageInner(props) {
662
546
  const overview = useGitOverview(props.repositoryKey, {
663
547
  headers: props.headers,
664
- initialData: props.initialData || null,
548
+ initialData: props.initialData?.overview || null,
665
549
  });
666
550
  const forks = useGitForks(props.repositoryKey, {
667
551
  headers: props.headers,
668
- });
669
- return h("div", {
670
- className: joinClassNames("git-browser-page", props.className),
671
- children: [
672
- h(RepositoryHeader, {
673
- current: "forks",
674
- headers: props.headers,
675
- key: "header",
676
- navigate: props.navigate,
677
- overview: overview.data,
678
- repositoryKey: props.repositoryKey,
679
- }),
680
- h(StatusBlock, {
681
- error: forks.error,
682
- key: "status",
683
- loading: overview.loading || forks.loading,
684
- children: h(Card, {
685
- title: "Fork Network",
686
- subtitle: "Create forks, then sync them against upstream from this page.",
687
- children: h("ul", {
688
- className: "git-browser-list",
689
- children: (forks.data || []).map((fork) => h(ForkRow, {
690
- fork,
691
- headers: props.headers,
692
- key: fork.fork_repository_id,
693
- repositoryKey: props.repositoryKey,
694
- })),
695
- }),
696
- }),
697
- }),
698
- ],
552
+ initialData: props.initialData?.forks || null,
553
+ });
554
+ return h(GitRepositoryShell, {
555
+ actions: defaultActionBar(props.repositoryKey, props.headers),
556
+ className: props.className,
557
+ error: forks.error,
558
+ loading: overview.loading || forks.loading,
559
+ page: "forks",
560
+ repositoryKey: props.repositoryKey,
561
+ social: overview.data?.social,
562
+ stats: overviewStats(overview.data),
563
+ subtitle: defaultSubtitle(props.repositoryKey, overview.data),
564
+ children: h("section", {
565
+ className: "git-browser-card",
566
+ children: [
567
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Fork Network" }) }),
568
+ h(GitForkList, { forks: forks.data || [], headers: props.headers, key: "list", repositoryKey: props.repositoryKey }),
569
+ ],
570
+ }),
699
571
  });
700
572
  }
701
573
  function GitRepositoryActivityPageInner(props) {
702
574
  const overview = useGitOverview(props.repositoryKey, {
703
575
  headers: props.headers,
704
- initialData: props.initialData || null,
576
+ initialData: props.initialData?.overview || null,
705
577
  });
706
578
  const activity = useGitActivity(props.repositoryKey, {
707
579
  headers: props.headers,
580
+ initialData: props.initialData?.activity || null,
581
+ });
582
+ return h(GitRepositoryShell, {
583
+ className: props.className,
584
+ error: activity.error,
585
+ loading: overview.loading || activity.loading,
586
+ page: "activity",
587
+ repositoryKey: props.repositoryKey,
588
+ social: overview.data?.social,
589
+ stats: overviewStats(overview.data),
590
+ subtitle: defaultSubtitle(props.repositoryKey, overview.data),
591
+ children: h("section", {
592
+ className: "git-browser-card",
593
+ children: [
594
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Activity Timeline" }) }),
595
+ h(GitActivityList, { activity: activity.data || [], key: "body" }),
596
+ ],
597
+ }),
708
598
  });
709
- return h("div", {
710
- className: joinClassNames("git-browser-page", props.className),
711
- children: [
712
- h(RepositoryHeader, {
713
- current: "activity",
714
- headers: props.headers,
715
- key: "header",
716
- navigate: props.navigate,
717
- overview: overview.data,
718
- repositoryKey: props.repositoryKey,
719
- }),
720
- h(StatusBlock, {
721
- error: activity.error,
722
- key: "status",
723
- loading: overview.loading || activity.loading,
724
- children: h(Card, {
725
- title: "Activity Timeline",
726
- children: h("ul", {
727
- className: "git-browser-list",
728
- children: (activity.data || []).map((entry) => (h("li", {
729
- className: "git-browser-list-item",
730
- key: entry.id,
731
- children: [
732
- h("strong", { key: "summary", children: entry.summary }),
733
- h("div", { className: "git-browser-note", key: "meta", children: `${entry.kind} · actor ${entry.actor_id} · ${formatDate(entry.created_at)}` }),
734
- ],
735
- }))),
736
- }),
599
+ }
600
+ function GitRepositoryBranchesPageInner(props) {
601
+ const overview = useGitOverview(props.repositoryKey, {
602
+ headers: props.headers,
603
+ initialData: props.initialData?.overview || null,
604
+ });
605
+ const branches = useGitBranches(props.repositoryKey, {
606
+ headers: props.headers,
607
+ initialData: props.initialData?.branches || null,
608
+ });
609
+ return h(GitRepositoryShell, {
610
+ actions: h(GitRepositoryActionBar, {
611
+ children: h(GitBranchSelector, { headers: props.headers, repositoryKey: props.repositoryKey, selectedBranch: overview.data?.repository.repository.current_branch }),
612
+ }),
613
+ className: props.className,
614
+ error: branches.error,
615
+ loading: overview.loading || branches.loading,
616
+ page: "branches",
617
+ repositoryKey: props.repositoryKey,
618
+ social: overview.data?.social,
619
+ stats: overviewStats(overview.data),
620
+ subtitle: defaultSubtitle(props.repositoryKey, overview.data),
621
+ children: h("section", {
622
+ className: "git-browser-card",
623
+ children: [
624
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Branches" }) }),
625
+ h(GitBranchList, { branches: branches.data || [], key: "list", repositoryKey: props.repositoryKey }),
626
+ ],
627
+ }),
628
+ });
629
+ }
630
+ function GitRepositoryTagsPageInner(props) {
631
+ const overview = useGitOverview(props.repositoryKey, {
632
+ headers: props.headers,
633
+ initialData: props.initialData?.overview || null,
634
+ });
635
+ const tags = useGitTags(props.repositoryKey, {
636
+ headers: props.headers,
637
+ initialData: props.initialData?.tags || null,
638
+ });
639
+ return h(GitRepositoryShell, {
640
+ actions: h(GitRepositoryActionBar, {
641
+ children: h(GitTagSelector, { headers: props.headers, repositoryKey: props.repositoryKey }),
642
+ }),
643
+ className: props.className,
644
+ error: tags.error,
645
+ loading: overview.loading || tags.loading,
646
+ page: "tags",
647
+ repositoryKey: props.repositoryKey,
648
+ social: overview.data?.social,
649
+ stats: overviewStats(overview.data),
650
+ subtitle: defaultSubtitle(props.repositoryKey, overview.data),
651
+ children: h("section", {
652
+ className: "git-browser-card",
653
+ children: [
654
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Tags" }) }),
655
+ h(GitTagList, { key: "list", repositoryKey: props.repositoryKey, tags: tags.data || [] }),
656
+ ],
657
+ }),
658
+ });
659
+ }
660
+ function GitRepositorySearchPageInner(props) {
661
+ const overview = useGitOverview(props.repositoryKey, {
662
+ headers: props.headers,
663
+ initialData: props.initialData?.overview || null,
664
+ });
665
+ const [query, setQuery] = useState(text(props.query));
666
+ const results = useGitSearch(props.repositoryKey, {
667
+ enabled: Boolean(query),
668
+ headers: props.headers,
669
+ initialData: props.initialData?.search || null,
670
+ path: props.path,
671
+ query,
672
+ ref: props.refName || overview.data?.repository.repository.current_branch || "HEAD",
673
+ });
674
+ return h(GitRepositoryShell, {
675
+ className: props.className,
676
+ error: results.error,
677
+ loading: overview.loading || results.loading,
678
+ page: "search",
679
+ repositoryKey: props.repositoryKey,
680
+ social: overview.data?.social,
681
+ stats: overviewStats(overview.data),
682
+ subtitle: defaultSubtitle(props.repositoryKey, overview.data),
683
+ children: h("section", {
684
+ className: "git-browser-card",
685
+ children: [
686
+ h("div", {
687
+ className: "git-browser-card-header",
688
+ key: "header",
689
+ children: [
690
+ h("h2", { className: "git-browser-card-title", key: "title", children: "Search" }),
691
+ h("input", {
692
+ className: "git-browser-input",
693
+ key: "input",
694
+ onChange: (event) => setQuery(text(event.target?.value)),
695
+ placeholder: "Search this repository",
696
+ value: query,
697
+ }),
698
+ ],
737
699
  }),
738
- }),
739
- ],
700
+ h(GitSearchResults, { key: "results", repositoryKey: props.repositoryKey, results: results.data }),
701
+ ],
702
+ }),
703
+ });
704
+ }
705
+ function GitRepositoryBlamePageInner(props) {
706
+ const overview = useGitOverview(props.repositoryKey, {
707
+ headers: props.headers,
708
+ initialData: props.initialData?.overview || null,
709
+ });
710
+ const blame = useGitBlame(props.repositoryKey, {
711
+ headers: props.headers,
712
+ path: props.path,
713
+ ref: props.refName || overview.data?.repository.repository.current_branch || "HEAD",
714
+ });
715
+ return h(GitRepositoryShell, {
716
+ className: props.className,
717
+ error: blame.error,
718
+ loading: overview.loading || blame.loading,
719
+ page: "blame",
720
+ repositoryKey: props.repositoryKey,
721
+ social: overview.data?.social,
722
+ stats: overviewStats(overview.data),
723
+ subtitle: props.path ? `Blame for ${props.path}` : defaultSubtitle(props.repositoryKey, overview.data),
724
+ children: h("section", {
725
+ className: "git-browser-card",
726
+ children: [
727
+ h("div", { className: "git-browser-card-header", key: "header", children: h("h2", { className: "git-browser-card-title", children: "Blame" }) }),
728
+ h(GitBlameView, { blame: blame.data, key: "view", refName: props.refName, repositoryKey: props.repositoryKey }),
729
+ ],
730
+ }),
731
+ });
732
+ }
733
+ function GitRepositoryComparePageInner(props) {
734
+ const overview = useGitOverview(props.repositoryKey, {
735
+ headers: props.headers,
736
+ initialData: props.initialData?.overview || null,
737
+ });
738
+ const diff = useGitDiff(props.repositoryKey, {
739
+ baseRef: props.baseRef,
740
+ headRef: props.headRef,
741
+ headers: props.headers,
742
+ initialData: props.initialData?.compare || null,
743
+ path: props.path,
744
+ });
745
+ return h(GitRepositoryShell, {
746
+ className: props.className,
747
+ error: diff.error,
748
+ loading: overview.loading || diff.loading,
749
+ page: "compare",
750
+ repositoryKey: props.repositoryKey,
751
+ social: overview.data?.social,
752
+ stats: overviewStats(overview.data),
753
+ subtitle: `${props.baseRef} → ${props.headRef}`,
754
+ children: h(GitDiffView, { diff: diff.data }),
740
755
  });
741
756
  }
742
757
  function GitRepositoryOverviewPage(props) {
@@ -763,5 +778,20 @@ function GitRepositoryForksPage(props) {
763
778
  function GitRepositoryActivityPage(props) {
764
779
  return withBrowserProvider(props, () => h(GitRepositoryActivityPageInner, props));
765
780
  }
766
- export { GitBrowserProvider, GitRepositoryActivityPage, GitRepositoryCodePage, GitRepositoryCommitPage, GitRepositoryCommitsPage, GitRepositoryForksPage, GitRepositoryOverviewPage, GitRepositoryReleasePage, GitRepositoryReleasesPage, };
781
+ function GitRepositoryBranchesPage(props) {
782
+ return withBrowserProvider(props, () => h(GitRepositoryBranchesPageInner, props));
783
+ }
784
+ function GitRepositoryTagsPage(props) {
785
+ return withBrowserProvider(props, () => h(GitRepositoryTagsPageInner, props));
786
+ }
787
+ function GitRepositorySearchPage(props) {
788
+ return withBrowserProvider(props, () => h(GitRepositorySearchPageInner, props));
789
+ }
790
+ function GitRepositoryBlamePage(props) {
791
+ return withBrowserProvider(props, () => h(GitRepositoryBlamePageInner, props));
792
+ }
793
+ function GitRepositoryComparePage(props) {
794
+ return withBrowserProvider(props, () => h(GitRepositoryComparePageInner, props));
795
+ }
796
+ export { GitBrowserProvider, GitRepositoryActivityPage, GitRepositoryBlamePage, GitRepositoryBranchesPage, GitRepositoryCodePage, GitRepositoryCommitPage, GitRepositoryCommitsPage, GitRepositoryComparePage, GitRepositoryForksPage, GitRepositoryOverviewPage, GitRepositoryReleasePage, GitRepositoryReleasesPage, GitRepositorySearchPage, GitRepositoryTagsPage, };
767
797
  //# sourceMappingURL=index.js.map