Skip to content

Commit 3a21bb9

Browse files
committed
enh: adjust layout
1 parent 631720d commit 3a21bb9

File tree

1 file changed

+103
-94
lines changed

1 file changed

+103
-94
lines changed

ui/src/resourceedit.vue

Lines changed: 103 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,30 @@
88
<b-tab title="Apps">
99
<template v-slot:title>
1010
Apps
11-
<span style="opacity: 0.6; font-size: 80%">{{resource.config.services.length}}</span>
11+
<span class="resouce-apps-count__span">{{resource.config.services.length}}</span>
1212
</template>
1313
</b-tab>
1414
</b-tabs>
1515
</b-container>
1616
</div>
17-
<b-form class="page-content">
18-
<b-container>
19-
<br>
20-
21-
<div v-if="tab == 0">
22-
<div style="padding-bottom: 10px">
23-
<b-form-checkbox v-model="resource.active">Active</b-form-checkbox>
24-
<p>
25-
<small>Uncheck this to temporarily disable this resource.</small>
26-
</p>
27-
</div>
17+
<b-form>
18+
<div v-if="tab == 0" class="page-content">
19+
<b-container>
20+
<b-row>
21+
<b-col cols="12">
22+
<b-form-checkbox v-model="resource.active">Active</b-form-checkbox>
23+
<p>
24+
<small>Uncheck this to temporarily disable this resource.</small>
25+
</p>
26+
</b-col>
27+
</b-row>
2828

2929
<b-row>
3030
<b-col cols="3">
3131
<span class="form-header">Name *</span>
3232
</b-col>
3333
<b-col cols="9">
3434
<b-input type="text" v-model="resource.name" placeholder="Resource Name"/>
35-
<br>
3635
</b-col>
3736
</b-row>
3837

@@ -43,7 +42,6 @@
4342
<b-col cols="9">
4443
<p>
4544
<contact :id="resource.user_id"/>
46-
<br>
4745
<small>Users who registered this resource and administer this resource.</small>
4846
</p>
4947
</b-col>
@@ -92,8 +90,6 @@
9290
<small>Please select projects that you'd like enable this resource. Any jobs submitted by any member of specified project will be executed on this resource. You have to be listed as administrator of the project to be able to select it.</small>
9391
</p>
9492
</b-col>
95-
<br>
96-
<br>
9793
</b-row>
9894

9995
<b-row>
@@ -102,7 +98,6 @@
10298
</b-col>
10399
<b-col cols="9">
104100
<b-input type="text" v-model.trim="resource.avatar" placeholder="Avatar URL"/>
105-
<br>
106101
</b-col>
107102
</b-row>
108103

@@ -169,28 +164,27 @@
169164
</b-col>
170165
<b-col cols="9">
171166
<p>
172-
<b>Public Key</b>
173-
<br>
167+
<b>Public Key</b><br/>
174168
<small>The following ssh public key should be stored in ~/.ssh/authorized_keys on this resource.</small>
175169
<b-form-textarea :rows="6" v-model="resource.config.ssh_public"/>
176170
</p>
177171
<p>
178-
<b>Private Key</b>
179-
<br>
172+
<b>Private Key</b><br/>
180173
<small>Brainlife will use the following private key to access this resource (You should not have to copy/paste this out of here).</small>
181174
<b-form-checkbox v-if="resource.config.enc_ssh_private === true" v-model="resource.config.enc_ssh_private">Use the current private key</b-form-checkbox>
182175
<b-form-textarea v-if="resource.config.enc_ssh_private !== true" :rows="3" v-model="resource.config.enc_ssh_private"/>
183176
</p>
184177
<p>
185-
<b-btn @click="reset_sshkey" size="sm">Issue New Keypair</b-btn>
178+
<b-btn @click="reset_sshkey" size="sm" :disabled="resetting_sshkey">Issue New Keypair</b-btn>
186179
</p>
187180

188181
</b-col>
189182
</b-row>
183+
</b-container>
184+
</div>
190185

191-
</div><!--end of detail tab-->
192-
193-
<div v-if="tab == 1">
186+
<div v-if="tab == 1" class="page-content">
187+
<b-container>
194188
<p>
195189
<b-input-group prepend="Max Jobs">
196190
<b-input type="text" v-model="resource.config.maxtask"/>
@@ -201,37 +195,42 @@
201195
<p>
202196
<small>The following Apps are allowed to run on this resource.</small>
203197
</p>
204-
<div v-for="(service, idx) in resource.config.services" :key="idx" style="margin-bottom: 5px;">
205-
<b-button @click="remove_service(service)" size="sm" text="Button" variant="danger" style="float: right;"><icon name="trash"/></b-button>
206-
<div style="padding-right: 50px;">
207-
<b-input-group prepend="Name">
208-
<b-form-input v-model="service.name" list="service_names" trim></b-form-input>
209-
<datalist id="service_names">
210-
<option v-for="service in service_names">{{service}}</option>
211-
</datalist>
212-
<b-input-group-prepend is-text>Score</b-input-group-prepend>
213-
<b-form-input v-model="service.score"></b-form-input>
214-
</b-input-group>
215-
</div>
198+
<div v-for="(service, idx) in resource.config.services" :key="idx" class="resource-apps-detail__div">
199+
<b-row>
200+
<b-col>
201+
<b-input-group>
202+
<b-input-group-prepend is-text>Name</b-input-group-prepend>
203+
<b-form-input v-model="service.name" list="service_names" trim></b-form-input>
204+
<datalist id="service_names">
205+
<option v-for="service in service_names">{{service}}</option>
206+
</datalist>
207+
<b-input-group-prepend is-text>Score</b-input-group-prepend>
208+
<b-form-input v-model="service.score"></b-form-input>
209+
</b-input-group>
210+
</b-col>
211+
<b-col cols="auto">
212+
<b-button @click="remove_service(service)" size="sm" text="Button" variant="danger"><icon name="trash"/></b-button>
213+
</b-col>
214+
</b-row>
216215
</div>
217216
<p>
218217
<b-btn @click="add_service" variant="success" size="sm">Add App</b-btn>
219218
</p>
220-
</div>
221-
<div class="page-footer">
222-
<b-container>
223-
<b-button variant="danger" @click="remove" v-if="this.resource._id" style="float: left;"><icon name="trash"/> Remove</b-button>
224-
<b-button variant="secondary" @click="cancel">Cancel</b-button>
225-
<b-button variant="primary" @click="submit" :disabled="submitting"><icon v-if="submitting" name="cog" spin/> Submit</b-button>
226-
</b-container>
227-
</div>
228-
229-
<br>
230-
<br>
231-
<br>
232-
<br>
233-
<br>
234-
</b-container>
219+
</b-container>
220+
</div>
221+
<div class="page-footer">
222+
<b-container>
223+
<b-row no-gutters>
224+
<b-col cols="auto">
225+
<b-button variant="danger" @click="remove" v-if="this.resource._id"><icon name="trash"/> Remove</b-button>
226+
</b-col>
227+
<b-col>
228+
<b-button variant="secondary" @click="cancel">Cancel</b-button>
229+
<b-button variant="primary" @click="submit" :disabled="submitting"><icon v-if="submitting" name="cog" spin/> Submit</b-button>
230+
</b-col>
231+
</b-row>
232+
</b-container>
233+
</div>
235234
<!--
236235
<div v-if="config.debug">
237236
<pre>{{JSON.stringify(resource, null, 4)}}</pre>
@@ -249,8 +248,8 @@ import contactlist from '@/components/contactlist'
249248
import contact from '@/components/contact'
250249
import tageditor from '@/components/tageditor'
251250
252-
//let's lazy fetch node-forge (it's pretty big..)
253-
const getForge = ()=>import('node-forge')
251+
// Lazy import, given the module is big
252+
const getForge = () => import('node-forge')
254253
255254
export default {
256255
components: {
@@ -262,38 +261,31 @@ export default {
262261
data () {
263262
return {
264263
resource: null,
265-
266264
projects: null,
267-
268265
tab: 0,
269-
270266
envs_: "",
271-
//global: false,
272-
//archive_access: false,
273-
274-
service_names: [], //all services that user can choose from
275-
267+
service_names: [], // All services that user can choose from
276268
submitting: false,
277-
269+
resetting_sshkey: false,
278270
config: Vue.config,
279271
}
280272
},
281273
282274
mounted: function() {
283275
284-
//load all apps service names
276+
// Load all apps service names
285277
this.$http.get("app", {params: {
286278
select: "github",
287279
limit: 1000,
288280
}}).then(res=>{
289-
this.service_names = res.data.apps.map(app=>app.github);
290-
this.service_names = [...new Set(this.service_names)]; //debupe
291-
this.service_names = this.service_names.filter(name=>name && name.includes("/")); //remove odd looking service names
281+
this.service_names = res.data.apps.map(app => app.github);
282+
this.service_names = [...new Set(this.service_names)]; // remove duplicates
283+
this.service_names = this.service_names.filter(name => name && name.includes("/")); // remove odd looking service names
292284
this.service_names.sort();
293285
});
294286
295287
if(this.$route.params.id !== '_') {
296-
//TODO use resource_cache mixin?
288+
// TODO use resource_cache mixin?
297289
this.$http.get(Vue.config.amaretti_api+'/resource', {params: {
298290
find: JSON.stringify({_id: this.$route.params.id})
299291
}}).then(res=>{
@@ -318,12 +310,11 @@ export default {
318310
this.reset_sshkey();
319311
this.loadProjects();
320312
}
321-
322313
},
323314
324315
methods: {
325316
loadProjects() {
326-
//load project that user can share this resource with
317+
// Load projects that user can share this resource with
327318
this.$http.get('project', {params: {
328319
find: JSON.stringify({
329320
removed: false,
@@ -353,7 +344,7 @@ export default {
353344
});
354345
}
355346
356-
//add private groups that user doesn't have access to.. so the value won't disappear
347+
// Add groups that user doesn't have access to, so the selection will not disappear
357348
this.resource.gids.forEach(gid => {
358349
const project = this.projects.find(p => p.group_id == gid);
359350
if (!project) {
@@ -387,26 +378,33 @@ export default {
387378
},
388379
389380
reset_sshkey() {
390-
delete this.resource.config.enc_ssh_private;
391-
getForge().then(forge=>{
392-
//publicKeyToOpenSSH only works for rsa.. not forge.pki.ed25519
393-
forge.pki.rsa.generateKeyPair({bits: 2048, workers: 2/*e: 0x10001*/}, (err, keypair)=>{
394-
if(err) {
395-
this.$notify({type: 'error', text: err});
396-
return;
397-
}
398-
Vue.set(this.resource.config, 'ssh_public', forge.ssh.publicKeyToOpenSSH(keypair.publicKey));//, "pubkey comment");
399-
Vue.set(this.resource.config, 'enc_ssh_private', forge.ssh.privateKeyToOpenSSH(keypair.privateKey));
400-
});
401-
});
381+
if (this.resetting_sshkey) return;
382+
this.resetting_sshkey = true;
383+
getForge()
384+
.then(forge => {
385+
forge.pki.rsa.generateKeyPair({bits: 2048, workers: 2 }, (err, keypair) => {
386+
if (err) {
387+
this.$notify({type: 'error', text: err});
388+
this.resetting_sshkey = false;
389+
return;
390+
}
391+
delete this.resource.config.enc_ssh_private;
392+
Vue.set(this.resource.config, 'ssh_public', forge.ssh.publicKeyToOpenSSH(keypair.publicKey));
393+
Vue.set(this.resource.config, 'enc_ssh_private', forge.ssh.privateKeyToOpenSSH(keypair.privateKey));
394+
this.resetting_sshkey = false;
395+
});
396+
})
397+
.catch(err => {
398+
this.$notify({type: 'error', text: err});
399+
this.resetting_sshkey = false;
400+
})
402401
},
403402
404-
submit(evt) {
405-
evt.preventDefault(); //TODO do I need this?
406-
if(this.submitting) return; //prevent double submission..
403+
submit() {
404+
if (this.submitting) return; // Prevent double submission
407405
this.submitting = true;
408-
//validate things
409-
if(this.envs_ && this.envs_.trim()) {
406+
407+
if (this.envs_ && this.envs_.trim()) {
410408
try {
411409
this.resource.envs = JSON.parse(this.envs_);
412410
} catch(err) {
@@ -415,25 +413,22 @@ export default {
415413
return;
416414
}
417415
}
418-
if(!this.resource.gids.length) {
416+
if (!this.resource.gids.length) {
419417
this.$notify({type: 'error', text: "Please specify at least 1 project to use this resource"});
420418
this.submitting = false;
421419
return;
422420
}
423421
424-
if(this.resource._id) {
425-
//update
422+
if (this.resource._id) { // Update resource
426423
this.$http.put(Vue.config.amaretti_api+'/resource/'+this.resource._id, this.resource).then(res=>{
427-
//this.$router.push('/resource/'+this.resource._id);
428424
this.$router.go(-1);
429425
this.submitting = false;
430426
}).catch(err=>{
431427
this.$notify({text: err.response.data.message, type: 'error' });
432428
console.error(err);
433429
this.submitting = false;
434430
});
435-
} else {
436-
//create
431+
} else { // Create resource
437432
delete this.resource._id;
438433
this.$http.post(Vue.config.amaretti_api+'/resource', this.resource).then(res=>{
439434
this.$router.replace('/resource/'+res.data._id);
@@ -473,10 +468,24 @@ export default {
473468
}
474469
.page-content {
475470
margin-top: 40px;
471+
padding-bottom: 60px;
472+
}
473+
.page-content .container {
474+
margin-top: 2em;
475+
}
476+
.page-content .container .row {
477+
margin-bottom: 1em;
476478
}
477479
small {
478480
opacity: 0.5;
479481
}
482+
.resource-apps-detail__div {
483+
margin-bottom: 1em;
484+
}
485+
.resouce-apps-count__span {
486+
opacity: 0.6;
487+
font-size: 80%;
488+
}
480489
.resource-projects-all_admin-message {
481490
color: #C00;
482491
}

0 commit comments

Comments
 (0)