Charlie commited on
Commit
2fc767f
·
1 Parent(s): 53475ee

update files

Browse files
Files changed (4) hide show
  1. dist/main.js +81 -9
  2. index.html +3 -0
  3. src/main.ts +106 -8
  4. styles/main.css +4 -0
dist/main.js CHANGED
@@ -299,7 +299,46 @@ async function getOrganizationInfo(accessToken) {
299
  }
300
  return response.json();
301
  }
302
- async function createRepository(accessToken, name, organization) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  const response = await fetch("https://huggingface.co/api/repos/create", {
304
  method: "POST",
305
  headers: {
@@ -316,6 +355,15 @@ async function createRepository(accessToken, name, organization) {
316
  if (!response.ok) {
317
  throw new Error(`Failed to create repository: ${response.statusText}`);
318
  }
 
 
 
 
 
 
 
 
 
319
  }
320
  var init = async () => {
321
  await oauthManager.handleRedirect();
@@ -332,19 +380,34 @@ var init = async () => {
332
  const repoNameInput = document.getElementById(
333
  "repo-name"
334
  );
 
 
 
 
 
 
335
  if (createRepoButton && repoNameInput) {
336
  createRepoButton.onclick = async () => {
337
  const repoName = repoNameInput.value.trim();
338
- const orgSelect = document.getElementById(
339
  "org-select"
340
  );
341
  if (repoName) {
342
  try {
343
- const selectedOrg = orgSelect?.value || void 0;
344
- console.log({ selectedOrg });
345
- await createRepository(accessToken, repoName, selectedOrg);
 
 
 
 
 
 
346
  repoNameInput.value = "";
347
- alert("Repository created successfully!");
 
 
 
348
  } catch (error) {
349
  console.error("Failed to create repository:", error);
350
  alert("Failed to create repository. Please try again.");
@@ -352,11 +415,20 @@ var init = async () => {
352
  }
353
  };
354
  }
 
 
 
 
 
 
 
 
 
 
 
 
355
  try {
356
  const orgInfo = await getOrganizationInfo(accessToken);
357
- const orgSelect = document.getElementById(
358
- "org-select"
359
- );
360
  if (orgSelect && orgInfo.orgs) {
361
  orgInfo.orgs.forEach((org) => {
362
  const option = document.createElement("option");
 
299
  }
300
  return response.json();
301
  }
302
+ async function getOrganizationMembers(accessToken, organization) {
303
+ const response = await fetch(
304
+ `https://huggingface.co/api/organizations/${organization}/members`,
305
+ {
306
+ headers: {
307
+ Authorization: `Bearer ${accessToken}`
308
+ }
309
+ }
310
+ );
311
+ if (!response.ok) {
312
+ throw new Error(
313
+ `Failed to fetch organization members: ${response.statusText}`
314
+ );
315
+ }
316
+ return response.json();
317
+ }
318
+ async function createResourceGroup(accessToken, organization, name, members) {
319
+ const response = await fetch(
320
+ `https://huggingface.co/api/organizations/${organization}/resource-groups`,
321
+ {
322
+ method: "POST",
323
+ headers: {
324
+ "Content-Type": "application/json",
325
+ Authorization: `Bearer ${accessToken}`
326
+ },
327
+ body: JSON.stringify({
328
+ name,
329
+ description: `Resource group for repository ${name}`,
330
+ users: members.map((member) => ({
331
+ user: member.user,
332
+ role: "admin"
333
+ }))
334
+ })
335
+ }
336
+ );
337
+ if (!response.ok) {
338
+ throw new Error(`Failed to create resource group: ${response.statusText}`);
339
+ }
340
+ }
341
+ async function createRepository(accessToken, name, organization, resourceGroupName) {
342
  const response = await fetch("https://huggingface.co/api/repos/create", {
343
  method: "POST",
344
  headers: {
 
355
  if (!response.ok) {
356
  throw new Error(`Failed to create repository: ${response.statusText}`);
357
  }
358
+ if (organization && resourceGroupName) {
359
+ const members = await getOrganizationMembers(accessToken, organization);
360
+ await createResourceGroup(
361
+ accessToken,
362
+ organization,
363
+ resourceGroupName,
364
+ members
365
+ );
366
+ }
367
  }
368
  var init = async () => {
369
  await oauthManager.handleRedirect();
 
380
  const repoNameInput = document.getElementById(
381
  "repo-name"
382
  );
383
+ const resourceGroupInput = document.getElementById(
384
+ "resource-group-name"
385
+ );
386
+ const resourceGroupContainer = document.getElementById(
387
+ "resource-group-container"
388
+ );
389
  if (createRepoButton && repoNameInput) {
390
  createRepoButton.onclick = async () => {
391
  const repoName = repoNameInput.value.trim();
392
+ const orgSelect2 = document.getElementById(
393
  "org-select"
394
  );
395
  if (repoName) {
396
  try {
397
+ const selectedOrg = orgSelect2?.value || void 0;
398
+ const resourceGroupName = selectedOrg ? resourceGroupInput?.value.trim() : void 0;
399
+ console.log({ selectedOrg, resourceGroupName });
400
+ await createRepository(
401
+ accessToken,
402
+ repoName,
403
+ selectedOrg,
404
+ resourceGroupName
405
+ );
406
  repoNameInput.value = "";
407
+ if (resourceGroupInput) {
408
+ resourceGroupInput.value = "";
409
+ }
410
+ alert("Repository and resource group created successfully!");
411
  } catch (error) {
412
  console.error("Failed to create repository:", error);
413
  alert("Failed to create repository. Please try again.");
 
415
  }
416
  };
417
  }
418
+ const orgSelect = document.getElementById(
419
+ "org-select"
420
+ );
421
+ if (orgSelect && resourceGroupContainer) {
422
+ orgSelect.onchange = () => {
423
+ if (orgSelect.value) {
424
+ resourceGroupContainer.style.removeProperty("display");
425
+ } else {
426
+ resourceGroupContainer.style.display = "none";
427
+ }
428
+ };
429
+ }
430
  try {
431
  const orgInfo = await getOrganizationInfo(accessToken);
 
 
 
432
  if (orgSelect && orgInfo.orgs) {
433
  orgInfo.orgs.forEach((org) => {
434
  const option = document.createElement("option");
index.html CHANGED
@@ -20,6 +20,9 @@
20
  <option value="">Personal Account</option>
21
  </select>
22
  <input type="text" id="repo-name" placeholder="Enter repository name" class="repo-input">
 
 
 
23
  <button id="create-repo" class="repo-button">Create Repository</button>
24
  </div>
25
  <div id="content">
 
20
  <option value="">Personal Account</option>
21
  </select>
22
  <input type="text" id="repo-name" placeholder="Enter repository name" class="repo-input">
23
+ <div id="resource-group-container" style="display: none;">
24
+ <input type="text" id="resource-group-name" placeholder="Enter resource group name" class="repo-input">
25
+ </div>
26
  <button id="create-repo" class="repo-button">Create Repository</button>
27
  </div>
28
  <div id="content">
src/main.ts CHANGED
@@ -17,6 +17,11 @@ interface WhoAmIResponse {
17
  orgs: OrganizationInfo[];
18
  }
19
 
 
 
 
 
 
20
  declare const window: HuggingFaceWindow;
21
 
22
  console.log("huggingface env", window.huggingface);
@@ -39,10 +44,63 @@ async function getOrganizationInfo(
39
  return response.json();
40
  }
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  async function createRepository(
43
  accessToken: string,
44
  name: string,
45
- organization?: string
 
46
  ): Promise<void> {
47
  const response = await fetch("https://huggingface.co/api/repos/create", {
48
  method: "POST",
@@ -61,6 +119,17 @@ async function createRepository(
61
  if (!response.ok) {
62
  throw new Error(`Failed to create repository: ${response.statusText}`);
63
  }
 
 
 
 
 
 
 
 
 
 
 
64
  }
65
 
66
  const init = async (): Promise<void> => {
@@ -83,6 +152,13 @@ const init = async (): Promise<void> => {
83
  const repoNameInput = document.getElementById(
84
  "repo-name"
85
  ) as HTMLInputElement;
 
 
 
 
 
 
 
86
  if (createRepoButton && repoNameInput) {
87
  createRepoButton.onclick = async () => {
88
  const repoName = repoNameInput.value.trim();
@@ -92,11 +168,22 @@ const init = async (): Promise<void> => {
92
  if (repoName) {
93
  try {
94
  const selectedOrg = orgSelect?.value || undefined;
95
-
96
- console.log({ selectedOrg });
97
- await createRepository(accessToken, repoName, selectedOrg);
 
 
 
 
 
 
 
 
98
  repoNameInput.value = ""; // Clear input after success
99
- alert("Repository created successfully!");
 
 
 
100
  } catch (error) {
101
  console.error("Failed to create repository:", error);
102
  alert("Failed to create repository. Please try again.");
@@ -105,14 +192,25 @@ const init = async (): Promise<void> => {
105
  };
106
  }
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  // Get organization info and populate org select after successful authentication
109
  try {
110
  const orgInfo = await getOrganizationInfo(accessToken);
111
 
112
  // Populate org select
113
- const orgSelect = document.getElementById(
114
- "org-select"
115
- ) as HTMLSelectElement;
116
  if (orgSelect && orgInfo.orgs) {
117
  orgInfo.orgs.forEach((org) => {
118
  const option = document.createElement("option");
 
17
  orgs: OrganizationInfo[];
18
  }
19
 
20
+ interface OrganizationMember {
21
+ user: string;
22
+ role: string;
23
+ }
24
+
25
  declare const window: HuggingFaceWindow;
26
 
27
  console.log("huggingface env", window.huggingface);
 
44
  return response.json();
45
  }
46
 
47
+ async function getOrganizationMembers(
48
+ accessToken: string,
49
+ organization: string
50
+ ): Promise<OrganizationMember[]> {
51
+ const response = await fetch(
52
+ `https://huggingface.co/api/organizations/${organization}/members`,
53
+ {
54
+ headers: {
55
+ Authorization: `Bearer ${accessToken}`,
56
+ },
57
+ }
58
+ );
59
+
60
+ if (!response.ok) {
61
+ throw new Error(
62
+ `Failed to fetch organization members: ${response.statusText}`
63
+ );
64
+ }
65
+
66
+ return response.json();
67
+ }
68
+
69
+ async function createResourceGroup(
70
+ accessToken: string,
71
+ organization: string,
72
+ name: string,
73
+ members: OrganizationMember[]
74
+ ): Promise<void> {
75
+ const response = await fetch(
76
+ `https://huggingface.co/api/organizations/${organization}/resource-groups`,
77
+ {
78
+ method: "POST",
79
+ headers: {
80
+ "Content-Type": "application/json",
81
+ Authorization: `Bearer ${accessToken}`,
82
+ },
83
+ body: JSON.stringify({
84
+ name: name,
85
+ description: `Resource group for repository ${name}`,
86
+ users: members.map((member) => ({
87
+ user: member.user,
88
+ role: "admin",
89
+ })),
90
+ }),
91
+ }
92
+ );
93
+
94
+ if (!response.ok) {
95
+ throw new Error(`Failed to create resource group: ${response.statusText}`);
96
+ }
97
+ }
98
+
99
  async function createRepository(
100
  accessToken: string,
101
  name: string,
102
+ organization?: string,
103
+ resourceGroupName?: string
104
  ): Promise<void> {
105
  const response = await fetch("https://huggingface.co/api/repos/create", {
106
  method: "POST",
 
119
  if (!response.ok) {
120
  throw new Error(`Failed to create repository: ${response.statusText}`);
121
  }
122
+
123
+ // If organization and resource group name are provided, create a resource group
124
+ if (organization && resourceGroupName) {
125
+ const members = await getOrganizationMembers(accessToken, organization);
126
+ await createResourceGroup(
127
+ accessToken,
128
+ organization,
129
+ resourceGroupName,
130
+ members
131
+ );
132
+ }
133
  }
134
 
135
  const init = async (): Promise<void> => {
 
152
  const repoNameInput = document.getElementById(
153
  "repo-name"
154
  ) as HTMLInputElement;
155
+ const resourceGroupInput = document.getElementById(
156
+ "resource-group-name"
157
+ ) as HTMLInputElement;
158
+ const resourceGroupContainer = document.getElementById(
159
+ "resource-group-container"
160
+ );
161
+
162
  if (createRepoButton && repoNameInput) {
163
  createRepoButton.onclick = async () => {
164
  const repoName = repoNameInput.value.trim();
 
168
  if (repoName) {
169
  try {
170
  const selectedOrg = orgSelect?.value || undefined;
171
+ const resourceGroupName = selectedOrg
172
+ ? resourceGroupInput?.value.trim()
173
+ : undefined;
174
+
175
+ console.log({ selectedOrg, resourceGroupName });
176
+ await createRepository(
177
+ accessToken,
178
+ repoName,
179
+ selectedOrg,
180
+ resourceGroupName
181
+ );
182
  repoNameInput.value = ""; // Clear input after success
183
+ if (resourceGroupInput) {
184
+ resourceGroupInput.value = ""; // Clear resource group input
185
+ }
186
+ alert("Repository and resource group created successfully!");
187
  } catch (error) {
188
  console.error("Failed to create repository:", error);
189
  alert("Failed to create repository. Please try again.");
 
192
  };
193
  }
194
 
195
+ // Handle org select change to show/hide resource group input
196
+ const orgSelect = document.getElementById(
197
+ "org-select"
198
+ ) as HTMLSelectElement;
199
+ if (orgSelect && resourceGroupContainer) {
200
+ orgSelect.onchange = () => {
201
+ if (orgSelect.value) {
202
+ resourceGroupContainer.style.removeProperty("display");
203
+ } else {
204
+ resourceGroupContainer.style.display = "none";
205
+ }
206
+ };
207
+ }
208
+
209
  // Get organization info and populate org select after successful authentication
210
  try {
211
  const orgInfo = await getOrganizationInfo(accessToken);
212
 
213
  // Populate org select
 
 
 
214
  if (orgSelect && orgInfo.orgs) {
215
  orgInfo.orgs.forEach((org) => {
216
  const option = document.createElement("option");
styles/main.css CHANGED
@@ -61,6 +61,10 @@ h2 {
61
  min-width: 200px;
62
  }
63
 
 
 
 
 
64
  .repo-input {
65
  flex: 1;
66
  padding: 0.8rem;
 
61
  min-width: 200px;
62
  }
63
 
64
+ #resource-group-container {
65
+ width: 100%;
66
+ }
67
+
68
  .repo-input {
69
  flex: 1;
70
  padding: 0.8rem;