IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
Browse Source

Added WBContainerRequestFields.

pull/1/head
parent
commit
c805147174
12 changed files with 280 additions and 10 deletions
  1. +1
    -0
      frontend/package.json
  2. +1
    -0
      frontend/rollup.config.js
  3. +7
    -0
      frontend/src/css/index.css
  4. +2
    -0
      frontend/src/html/index.html
  5. +11
    -8
      frontend/src/js/component/wb-common-fields.js
  6. +124
    -0
      frontend/src/js/component/wb-container-request-fields.js
  7. +78
    -0
      frontend/src/js/component/wb-name-and-uuid.js
  8. +2
    -0
      frontend/src/js/misc/arvados-object-name.js
  9. +3
    -0
      frontend/src/js/misc/arvados-type-name.js
  10. +5
    -0
      frontend/src/js/page/wb-process-view.js
  11. +40
    -0
      frontend/src/js/widget/wb-accordion.js
  12. +6
    -2
      frontend/src/js/widget/wb-table.js

+ 1
- 0
frontend/package.json View File

@@ -3,6 +3,7 @@
"@fortawesome/fontawesome-free": "^5.12.0",
"bootstrap": "^4.4.1",
"jquery": "^3.4.1",
"js-uuid": "0.0.6",
"linkstate": "^1.1.1",
"popper.js": "^1.16.1",
"preact": "^8.2.9",


+ 1
- 0
frontend/rollup.config.js View File

@@ -41,6 +41,7 @@ export default {
'node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.ttf': 'dist/webfonts/fa-brands-400.ttf',
'node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff': 'dist/webfonts/fa-brands-400.woff',
'node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff2': 'dist/webfonts/fa-brands-400.woff2',
'node_modules/js-uuid/js-uuid.js': 'dist/js/js-uuid.js',
verbose: true
}),
buble({jsx: 'h'}),


+ 7
- 0
frontend/src/css/index.css View File

@@ -0,0 +1,7 @@
pre.word-wrap {
white-space: pre-wrap; /* Since CSS 2.1 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}

+ 2
- 0
frontend/src/html/index.html View File

@@ -3,9 +3,11 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="/css/all.min.css" />
<link rel="stylesheet" type="text/css" href="/css/index.css" />
<script language="javascript" src="/js/jquery.min.js"></script>
<script language="javascript" src="/js/bootstrap.min.js"></script>
<script language="javascript" src="/js/fontawesome.min.js"></script>
<script language="javascript" src="/js/js-uuid.js"></script>
</head>
<body>
<script language="javascript" src="/js/app.min.js"></script>


+ 11
- 8
frontend/src/js/component/wb-common-fields.js View File

@@ -69,7 +69,11 @@ class WBCommonFields extends Component {
</div>
) ],
[ 'Modified by Client', item.modified_by_client_uuid ],
[ 'API Url', 'https://' + app.state.arvHost + '/arvados/v1' + item.href ],
[ 'API Url', (
<a href={ 'https://' + app.state.arvHost + '/arvados/v1' + item.href }>
{ 'https://' + app.state.arvHost + '/arvados/v1' + item.href }
</a>
) ],
[ 'ETag', item.etag ]
];
this.setState({ 'rows': rows });
@@ -78,13 +82,12 @@ class WBCommonFields extends Component {
render({}, { rows }) {
return (
<div>
<h1>Common Fields</h1>
{ rows ? (
<WBTable columns={ [ "Name", "Value" ] }
rows={ rows } />
) : <div>Loading...</div> }
</div>
rows ? (
<WBTable columns={ [ "Name", "Value" ] }
rows={ rows } />
) : (
<div>Loading...</div>
)
);
}
}


+ 124
- 0
frontend/src/js/component/wb-container-request-fields.js View File

@@ -0,0 +1,124 @@
import { h, Component } from 'preact';
import WBTable from 'wb-table';
import makeArvadosRequest from 'make-arvados-request';
import arvadosTypeName from 'arvados-type-name';
import arvadosObjectName from 'arvados-object-name';
import urlForObject from 'url-for-object';
import wbFormatDate from 'wb-format-date';
import WBNameAndUuid from 'wb-name-and-uuid';
import WBAccordion from 'wb-accordion';
class WBContainerRequestFields extends Component {
componentDidMount() {
this.prepareRows();
}
componentWillReceiveProps(nextProps) {
this.props = nextProps;
this.prepareRows();
}
prepareRows() {
let { uuid, app } = this.props;
let { arvHost, arvToken } = app.state;
let item;
let prom = makeArvadosRequest(arvHost, arvToken,
'/arvados/v1/container_requests/' + uuid);
prom = prom.then(xhr => (item = xhr.response));
prom = prom.then(() => {
let rows = [
[ 'Name', item.name ],
[ 'Description', item.description || (<i>{ String(item.description) }</i>) ],
[ 'Properties', (
<WBAccordion names={ ['Properties'] } cardHeaderClass="card-header-sm">
<pre class="word-wrap">{ JSON.stringify(item.properties, null, 2) }</pre>
</WBAccordion>
) ],
[ 'State', item.state ],
[ 'Requesting Container', (
<WBNameAndUuid app={ app } uuid={ item.requesting_container_uuid } />
) ],
[ 'Container', (
<WBNameAndUuid app={ app } uuid={ item.container_uuid } />
) ],
[ 'Container Count Max', item.container_count_max ],
[ 'Mounts', (
<WBAccordion names={ Object.keys(item.mounts) }
cardHeaderClass="card-header-sm">
{ Object.keys(item.mounts).map(k => (
<pre class="word-wrap">{ JSON.stringify(item.mounts[k], null, 2) }</pre>
)) }
</WBAccordion>
) ],
[ 'Runtime Constraints', (
<WBAccordion names={ ['Runtime Constraints'] }
cardHeaderClass="card-header-sm">
<pre class="word-wrap">{ JSON.stringify(item.runtime_constraints, null, 2) }</pre>
</WBAccordion>
) ],
[ 'Scheduling Parameters', (
<WBAccordion names={ ['Scheduling Parameters'] }
cardHeaderClass="card-header-sm">
<pre class="word-wrap">{ JSON.stringify(item.scheduling_parameters, null, 2) }</pre>
</WBAccordion>
) ],
[ 'Container Image', (
<WBNameAndUuid app={ app } uuid={ item.container_image } />
) ],
[ 'Environment', (
<WBAccordion names={ ['Environment'] }
cardHeaderClass="card-header-sm">
<pre class="word-wrap">{ JSON.stringify(item.environment, null, 2) }</pre>
</WBAccordion>
) ],
[ 'Working Directory', item.cwd ],
[ 'Command', (
<pre class="word-wrap">{ JSON.stringify(item.command) }</pre>
) ],
[ 'Output Path', item.output_path ],
[ 'Output Name', item.output_name ],
[ 'Output TTL', item.output_ttl ],
[ 'Priority', item.priority ],
[ 'Expires At', wbFormatDate(item.expires_at) ],
[ 'Use Existing', String(item.use_existing) ],
[ 'Log', (
<WBNameAndUuid app={ app } uuid={ item.log_uuid } />
) ],
[ 'Output', (
<WBNameAndUuid app={ app } uuid={ item.output_uuid } />
) ],
[ 'Filters', (
item.filters ? (<pre class="word-wrap">{ item.filters }</pre>) : (<i>{ String(item.filters) }</i>)
) ],
[ 'Runtime Token', item.runtime_token || (<i>{ String(item.runtime_token) }</i>) ],
[ 'Runtime User', (
<WBNameAndUuid app={ app } uuid={ item.runtime_user } />
) ],
[ 'Runtime Auth Scopes', (
item.runtime_auth_scopes ? (
<pre class="word-wrap">{ JSON.stringify(item.runtime_auth_scopes, null, 2) }</pre>
) : (
<i>{ String(item.runtime_auth_scopes) }</i>
)
) ]
];
this.setState({ 'rows': rows });
});
}
render({}, { rows }) {
return (
rows ? (
<WBTable columns={ [ "Name", "Value" ] }
headerClasses={ [ "col-sm-2", "col-sm-4" ] }
rows={ rows } />
) : (
<div>Loading...</div>
)
);
}
}
export default WBContainerRequestFields;

+ 78
- 0
frontend/src/js/component/wb-name-and-uuid.js View File

@@ -0,0 +1,78 @@
import { h, Component } from 'preact';
import makeArvadosRequest from 'make-arvados-request';
import urlForObject from 'url-for-object';
import arvadosObjectName from 'arvados-object-name';
import arvadosTypeName from 'arvados-type-name';
class WBNameAndUuid extends Component {
componentDidMount() {
let { uuid, app } = this.props;
let { arvHost, arvToken } = app.state;
if (!uuid)
return;
let prom = new Promise(accept => accept());
if (/[0-9a-f]{32}\+[0-9]+/g.exec(uuid)) {
let filters = [
['portable_data_hash', '=', uuid]
];
prom = prom.then(() => makeArvadosRequest(arvHost, arvToken,
'/arvados/v1/collections?filters=' +
encodeURIComponent(JSON.stringify(filters))));
prom = prom.then(xhr => {
if (xhr.response.items.length === 0) {
this.setState({
'item': {
'uuid': uuid,
'name': 'Collection with portable data hash ' + uuid
}
});
return;
}
let item = xhr.response.items[0];
if (xhr.response.items.length > 1)
item.name += ' +' + (xhr.response.items.length - 1) + ' others';
this.setState({ item });
});
} else if (/[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{15}/.exec(uuid)) {
let typeName = arvadosTypeName(uuid);
let prom = makeArvadosRequest(arvHost, arvToken,
'/arvados/v1/' + typeName + 's/' + uuid );
prom = prom.then(xhr => this.setState({
'item': xhr.response
}));
} else {
this.setState({
'item': {
'uuid': uuid
}
});
}
}
render({ uuid }, { item }) {
if (!uuid)
return (
<div><i>{ String(uuid) }</i></div>
);
return (
<div>
<div>
{ item ? (
<a href={ urlForObject(item) }>{ arvadosObjectName(item) }</a>
) : 'Loading...' }
</div>
<div>
{ uuid }
</div>
</div>
);
}
}
export default WBNameAndUuid;

+ 2
- 0
frontend/src/js/misc/arvados-object-name.js View File

@@ -4,6 +4,8 @@ function arvadosObjectName(item) {
let typeName = arvadosTypeName(item['uuid']);
if (typeName === 'user')
return (item.first_name + ' ' + item.last_name);
else if (typeName === 'container')
return ('Container running image ' + item.container_image);
else
return item.name;
}


+ 3
- 0
frontend/src/js/misc/arvados-type-name.js View File

@@ -9,6 +9,9 @@ const typeIdToName = {
};
function arvadosTypeName(id) {
if (!id)
return;
if (id.length === 5)
return typeIdToName[id];
else


+ 5
- 0
frontend/src/js/page/wb-process-view.js View File

@@ -7,6 +7,7 @@ import arvadosTypeName from 'arvados-type-name';
import urlForObject from 'url-for-object';
import detectHashes from 'detect-hashes';
import WBCommonFields from 'wb-common-fields';
import WBContainerRequestFields from 'wb-container-request-fields';
class WBProcessView extends Component {
constructor(...args) {
@@ -88,8 +89,12 @@ class WBProcessView extends Component {
This is the process view for { uuid }
</div>
<h2>Common Fields</h2>
<WBCommonFields app={ app } uuid={ uuid } />
<h2>Container Request Fields</h2>
<WBContainerRequestFields app={ app } uuid={ uuid } />
<div>
<a href="/browse">Click here</a>
</div>


+ 40
- 0
frontend/src/js/widget/wb-accordion.js View File

@@ -0,0 +1,40 @@
import { h, Component } from 'preact';
class WBAccordion extends Component {
constructor(...args) {
super(...args);
this.state.domId = 'accordion-' + uuid.v4();
this.state.headerDomIds = this.props.names.map(() => ('accordion-' + uuid.v4()));
this.state.collapseDomIds = this.props.names.map(() => ('accordion-' + uuid.v4()));
}
render({ children, names, cardHeaderClass }, { domId, headerDomIds, collapseDomIds }) {
return (
<div class="accordion" id={ domId }>
{ children.map((_, i) => (
<div class="card">
<div class={ cardHeaderClass} id={ headerDomIds[i] }>
<h2 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse" data-target={ '#' + collapseDomIds[i] } aria-expanded="false" aria-controls={ collapseDomIds[i] }>
{ names[i] }
</button>
</h2>
</div>
<div id={ collapseDomIds[i] } class="collapse" aria-labelledby={ headerDomIds[i] } data-parent={ '#' + domId }>
<div class="card-body">
{ children[i] }
</div>
</div>
</div>
)) }
</div>
);
}
};
WBAccordion.defaultProps = {
'cardHeaderClass': 'card-header'
};
export default WBAccordion;

+ 6
- 2
frontend/src/js/widget/wb-table.js View File

@@ -1,12 +1,12 @@
import { h, Component } from 'preact';
class WBTable extends Component {
render({ columns, rows }) {
render({ columns, rows, headerClasses }) {
return (
<table class="table table-striped table-hover">
<thead class="thead-light">
<tr>
{ columns.map(c => <th>{ c }</th>) }
{ columns.map((c, i) => <th class={ headerClasses[i] }>{ c }</th>) }
</tr>
</thead>
<tbody>
@@ -23,4 +23,8 @@ class WBTable extends Component {
}
}
WBTable.defaultProps = {
'headerClasses': []
};
export default WBTable;

Loading…
Cancel
Save