Skip to content

Commit 0b20a04

Browse files
authored
Merge pull request #11398 from Turbo87/trustpub-ui
Implement Trusted Publishing user interface
2 parents 46b5393 + b00a70f commit 0b20a04

File tree

18 files changed

+1231
-11
lines changed

18 files changed

+1231
-11
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import ApplicationAdapter from './application';
2+
3+
export default class TrustpubGitHubConfigAdapter extends ApplicationAdapter {
4+
pathForType() {
5+
return 'trusted_publishing/github_configs';
6+
}
7+
}

app/controllers/crate/settings.js renamed to app/controllers/crate/settings/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { task } from 'ember-concurrency';
77

88
export default class CrateSettingsController extends Controller {
99
@service notifications;
10+
@service store;
1011

1112
crate = null;
1213
username = '';
@@ -64,6 +65,22 @@ export default class CrateSettingsController extends Controller {
6465
this.notifications.error(message);
6566
}
6667
});
68+
69+
removeConfigTask = task(async config => {
70+
try {
71+
await config.destroyRecord();
72+
this.notifications.success('Trusted Publishing configuration removed successfully');
73+
} catch (error) {
74+
let message = 'Failed to remove Trusted Publishing configuration';
75+
76+
let detail = error.errors?.[0]?.detail;
77+
if (detail && !detail.startsWith('{')) {
78+
message += `: ${detail}`;
79+
}
80+
81+
this.notifications.error(message);
82+
}
83+
});
6784
}
6885

6986
function removeOwner(owners, target) {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import Controller from '@ember/controller';
2+
import { action } from '@ember/object';
3+
import { service } from '@ember/service';
4+
import { tracked } from '@glimmer/tracking';
5+
6+
import { task } from 'ember-concurrency';
7+
8+
export default class NewTrustedPublisherController extends Controller {
9+
@service notifications;
10+
@service store;
11+
@service router;
12+
13+
@tracked publisher = 'GitHub';
14+
@tracked repositoryOwner = '';
15+
@tracked repositoryName = '';
16+
@tracked workflowFilename = '';
17+
@tracked environment = '';
18+
@tracked repositoryOwnerInvalid = false;
19+
@tracked repositoryNameInvalid = false;
20+
@tracked workflowFilenameInvalid = false;
21+
22+
get crate() {
23+
return this.model.crate;
24+
}
25+
26+
get publishers() {
27+
return ['GitHub'];
28+
}
29+
30+
saveConfigTask = task(async () => {
31+
if (!this.validate()) return;
32+
33+
let config = this.store.createRecord('trustpub-github-config', {
34+
crate: this.crate,
35+
repository_owner: this.repositoryOwner,
36+
repository_name: this.repositoryName,
37+
workflow_filename: this.workflowFilename,
38+
environment: this.environment || null,
39+
});
40+
41+
try {
42+
// Save the new config on the backend
43+
await config.save();
44+
45+
this.repositoryOwner = '';
46+
this.repositoryName = '';
47+
this.workflowFilename = '';
48+
this.environment = '';
49+
50+
// Navigate back to the crate settings page
51+
this.notifications.success('Trusted Publishing configuration added successfully');
52+
this.router.transitionTo('crate.settings', this.crate.id);
53+
} catch (error) {
54+
// Notify the user
55+
let message = 'An error has occurred while adding the Trusted Publishing configuration';
56+
57+
let detail = error.errors?.[0]?.detail;
58+
if (detail && !detail.startsWith('{')) {
59+
message += `: ${detail}`;
60+
}
61+
62+
this.notifications.error(message);
63+
}
64+
});
65+
66+
validate() {
67+
this.repositoryOwnerInvalid = !this.repositoryOwner;
68+
this.repositoryNameInvalid = !this.repositoryName;
69+
this.workflowFilenameInvalid = !this.workflowFilename;
70+
71+
return !this.repositoryOwnerInvalid && !this.repositoryNameInvalid && !this.workflowFilenameInvalid;
72+
}
73+
74+
@action resetRepositoryOwnerValidation() {
75+
this.repositoryOwnerInvalid = false;
76+
}
77+
78+
@action resetRepositoryNameValidation() {
79+
this.repositoryNameInvalid = false;
80+
}
81+
82+
@action resetWorkflowFilenameValidation() {
83+
this.workflowFilenameInvalid = false;
84+
}
85+
}

app/models/trustpub-github-config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Model, { attr, belongsTo } from '@ember-data/model';
2+
3+
export default class TrustpubGitHubConfig extends Model {
4+
@belongsTo('crate', { async: true, inverse: null }) crate;
5+
@attr repository_owner;
6+
@attr repository_name;
7+
@attr workflow_filename;
8+
@attr environment;
9+
@attr('date') created_at;
10+
}

app/router.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ Router.map(function () {
1919
this.route('reverse-dependencies', { path: 'reverse_dependencies' });
2020

2121
this.route('owners');
22-
this.route('settings');
22+
this.route('settings', function () {
23+
this.route('new-trusted-publisher');
24+
});
2325
this.route('delete');
2426

2527
// Well-known routes

app/routes/crate/settings.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ export default class SettingsRoute extends AuthenticatedRoute {
66
@service router;
77
@service session;
88

9-
async afterModel(crate, transition) {
9+
async beforeModel(transition) {
10+
await super.beforeModel(...arguments);
11+
1012
let user = this.session.currentUser;
11-
let owners = await crate.owner_user;
13+
let owners = await this.modelFor('crate').owner_user;
1214
let isOwner = owners.some(owner => owner.id === user.id);
1315
if (!isOwner) {
1416
this.router.replaceWith('catch-all', {
@@ -17,10 +19,4 @@ export default class SettingsRoute extends AuthenticatedRoute {
1719
});
1820
}
1921
}
20-
21-
setupController(controller) {
22-
super.setupController(...arguments);
23-
let crate = this.modelFor('crate');
24-
controller.set('crate', crate);
25-
}
2622
}

app/routes/crate/settings/index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Route from '@ember/routing/route';
2+
import { service } from '@ember/service';
3+
4+
export default class SettingsIndexRoute extends Route {
5+
@service store;
6+
7+
async model() {
8+
let crate = this.modelFor('crate');
9+
10+
let githubConfigs = await this.store.query('trustpub-github-config', { crate: crate.name });
11+
12+
return { crate, githubConfigs };
13+
}
14+
15+
setupController(controller, { crate, githubConfigs }) {
16+
super.setupController(...arguments);
17+
18+
controller.set('crate', crate);
19+
controller.set('githubConfigs', githubConfigs);
20+
}
21+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Route from '@ember/routing/route';
2+
3+
export default class NewTrustedPublisherRoute extends Route {
4+
async model() {
5+
let crate = this.modelFor('crate');
6+
return { crate };
7+
}
8+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import ApplicationSerializer from './application';
2+
3+
export default class TrustpubGitHubConfigSerializer extends ApplicationSerializer {
4+
modelNameFromPayloadKey() {
5+
return 'trustpub-github-config';
6+
}
7+
8+
payloadKeyFromModelName() {
9+
return 'github_config';
10+
}
11+
}

app/styles/crate/settings.module.css renamed to app/styles/crate/settings/index.module.css

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.owners-header {
1+
.owners-header, .trusted-publishing-header {
22
display: flex;
33
justify-content: space-between;
44
align-items: center;
@@ -43,6 +43,30 @@
4343
}
4444
}
4545

46+
.trustpub {
47+
background-color: light-dark(white, #141413);
48+
border-radius: var(--space-3xs);
49+
box-shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321);
50+
51+
tbody > tr > td {
52+
border-top: 1px solid light-dark(hsla(51, 90%, 42%, .25), #232321);
53+
}
54+
55+
th, td {
56+
text-align: left;
57+
padding: var(--space-s) var(--space-m);
58+
}
59+
60+
.details {
61+
font-size: 0.85em;
62+
line-height: 1.5;
63+
}
64+
65+
.actions {
66+
text-align: right;
67+
}
68+
}
69+
4670
.email-column {
4771
width: 25%;
4872
color: var(--main-color-light);

0 commit comments

Comments
 (0)