Skip to content

Commit

Permalink
Minor fixes of styling, add codehilite, change datalink modal (#255)
Browse files Browse the repository at this point in the history
* Fix minor styling issues

* Fix rendering of filepath for files and images

* Fix column discover in mysql adapter

* Change the datalink modal for the results

* Fix rendering of arrays in a table cell

* Bump queryparser version to 0.7
  • Loading branch information
kimakan authored Jan 27, 2025
1 parent 0bb641a commit cc82a7d
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 61 deletions.
2 changes: 1 addition & 1 deletion daiquiri/auth/templates/account/account_profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ <h1>{% trans "Update profile" %}</h1>
{{ profile_form }}

<input type="submit" value="{% trans 'Update profile' %}" class="btn btn-primary" />
<input type="submit" name="cancel" value="{% trans 'Cancel' %}" class="btn btn-default" />
<input type="submit" name="cancel" value="{% trans 'Cancel' %}" class="btn btn-outline-secondary" />
</form>

{% endblock %}
2 changes: 1 addition & 1 deletion daiquiri/contact/templates/contact/contact.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h1>{% trans "Contact Form" %}</h1>
{{ form }}

<input type="submit" value="{% trans 'Send message' %}" class="btn {{ submit_danger|yesno:'btn-danger,btn-primary' }}" />
<input type="submit" name="cancel" value="{% trans 'Cancel' %}" class="btn btn-default" />
<input type="submit" name="cancel" value="{% trans 'Cancel' %}" class="btn btn-outline-secondary" />
</form>
{% else %}
<p>
Expand Down
14 changes: 9 additions & 5 deletions daiquiri/core/adapter/database/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,15 @@ def fetch_column(self, schema_name, table_name, column_name):
logger.error('Could not fetch %s.%s.%s (%s)', schema_name, table_name, column_name, e)
return {}
else:
return {
'name': row[0],
'datatype': row[1],
'indexed': bool(row[4])
}
if row is None:
logger.info(f'Could not fetch {schema_name}.{table_name}.{column_name}. Check if column, table and schema exist.')
return {}
else:
return {
'name': row[0],
'datatype': row[1],
'indexed': bool(row[4])
}

def fetch_column_names(self, schema_name, table_name):
# prepare sql string
Expand Down
13 changes: 10 additions & 3 deletions daiquiri/core/assets/js/components/table/TableCell.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'

import { getBasename, getFileUrl, getLinkUrl, getReferenceUrl,
import { getBasename, getFileUrl, getLinkUrl, getReferenceUrl, isImageColumn,
isModalColumn, isFileColumn, isLinkColumn } from '../../utils/table.js'

const TableCell = ({ column, value, rowIndex, columnIndex, setActive, showModal }) => {
Expand All @@ -10,6 +10,9 @@ const TableCell = ({ column, value, rowIndex, columnIndex, setActive, showModal
if (column.ucd && column.ucd.includes('meta.ref')) {
if (isModalColumn(column)) {
// render the modal
if (isImageColumn(column)) {
value = getBasename(value)
}
return (
<a href={getFileUrl(column, value)} onClick={(event) => {
event.preventDefault()
Expand All @@ -19,7 +22,7 @@ const TableCell = ({ column, value, rowIndex, columnIndex, setActive, showModal
} else if (isFileColumn(column)) {
// render a file link
return (
<a href={getFileUrl(column, value)} target="_blank" rel="noreferrer">{getBasename(value)}1</a>
<a href={getFileUrl(column, value)} target="_blank" rel="noreferrer">{getBasename(value)}</a>
)
} else if (isLinkColumn(column)) {
// render a regular link
Expand All @@ -34,7 +37,11 @@ const TableCell = ({ column, value, rowIndex, columnIndex, setActive, showModal
}
} else {
// this is not a reference, just render the value
return value
if (Array.isArray(value)) {
return `[${value.join(', ')}]`
} else {
return value
}
}
}

Expand Down
84 changes: 43 additions & 41 deletions daiquiri/core/assets/js/components/table/TableModalDatalinks.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { isEmpty, upperFirst } from 'lodash'
import { isEmpty } from 'lodash'

import { baseUrl } from 'daiquiri/core/assets/js/utils/meta'

Expand All @@ -13,47 +12,49 @@ const TableModalDatalinks = ({ dataLinkId, dataLinks }) => {
</p>
)
} else {
const semanticsList = dataLinks.reduce((semanticsList, dataLink) => (
semanticsList.includes(dataLink.semantics) ? semanticsList : [...semanticsList, dataLink.semantics]
), [])

return (
<>
{
semanticsList.map(semantics => {
const label = semantics.split('#')[1]

return (
<div key={semantics} className={classNames({'mt-2': semantics != semanticsList[0]})}>
<strong>{label ? upperFirst(label) : semantics}</strong>
const dlPreview = dataLinks.filter(dataLink => dataLink.semantics == '#preview')
const dlThis = dataLinks.filter(dataLink => dataLink.semantics == '#this')
const dlPreviewImages = dataLinks.filter(dataLink => dataLink.semantics == '#preview-image' || dataLink.semantics == '#preview-plot')

{
semantics == '#preview' ? (
dataLinks.filter(dataLink => dataLink.semantics == semantics).map((dataLink, dataLinkIndex) => (
<img key={dataLinkIndex} src={dataLink.access_url} className="d-block img-fluid" alt={dataLink.description} />
))
) : (
<ul className="list-unstyled">
{
dataLinks.filter(dataLink => dataLink.semantics == semantics).map((dataLink, dataLinkIndex) => (
<li key={dataLinkIndex} className="list-group-item">
<a href={dataLink.access_url} target="_blank" rel="noreferrer">{dataLink.description || dataLink.access_url}</a>
</li>
))
}
</ul>
)
}
</div>
)
})
}
<p className="mt-2">
<a href={`${baseUrl}/datalink/${dataLinkId}/`} target="_blank" rel="noreferrer">
{interpolate(gettext('Datalink page'), [dataLinkId])}
</a>
</p>
</>
return (
<div>
<ul className="list-unstyled">
{dlPreview.map((dataLink, index) => (
<li key={index}>
<a className="btn btn-primary btn-sm" href={dataLink.access_url} target="_blank" rel="noreferrer" data-bs-toggle="tooltip" title="Open viewer">
<i className="bi bi-eye"></i>
</a>
&nbsp;&nbsp;{dataLink.description}
</li>
))}
</ul>
<ul className="list-unstyled">
{dlThis.map((dataLink, index) => (
<li key={index}>
<a className="btn btn-primary btn-sm" href={dataLink.access_url} data-bs-toggle="tooltip" title="Download file">
<i className="bi bi-download"></i>
</a>
&nbsp;&nbsp;{dataLink.description}
</li>
))}
</ul>
<ul className="list-unstyled">
<li>
<a className="btn btn-primary btn-sm" href={`${baseUrl}/datalink/${dataLinkId}/`} target="_blank" rel="noreferrer" data-bs-toggle="tooltip" title="Open DataLink viewer">
<i className="bi bi-link-45deg"></i>
</a>
&nbsp;&nbsp;Show all Data Links
</li>
</ul>
<hr></hr>
{dlPreviewImages.map((dataLink, dataLinkIndex) => (
<div key={dataLinkIndex}>
<h5>{dataLink.description}</h5>
<img src={dataLink.access_url} className="d-block img-fluid" alt='Image is missing, please contact the administrator.' />
</div>
))}
</div>
)
}
}
Expand All @@ -64,3 +65,4 @@ TableModalDatalinks.propTypes = {
}

export default TableModalDatalinks

8 changes: 7 additions & 1 deletion daiquiri/core/assets/js/utils/table.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { baseUrl } from './meta'

export const getBasename = (string) => string.replace(/^.*[\\/]/, '')
export const getBasename = (string) => {
if (typeof string === 'string' || string instanceof String){
return string.replace(/^.*[\\/]/, '')
} else {
return string
}
}

export const getFileUrl = (column, value) => `${baseUrl}/files/${value}`

Expand Down
1 change: 1 addition & 0 deletions daiquiri/core/assets/scss/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ $bootstrap-icons-font-dir: '~bootstrap-icons/font/fonts';

@import 'base/browser';
@import 'base/card';
@import 'base/codehilite';
@import 'base/fonts';
@import 'base/footer';
@import 'base/form';
Expand Down
86 changes: 86 additions & 0 deletions daiquiri/core/assets/scss/base/codehilite.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
pre {
display: block;
padding: 9.5px;
margin: 0 0 10px;
font-size: 13px;
line-height: 125%;
color: #333;
word-break: break-all;
word-wrap: break-word;
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 4px;
}
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.codehilite .hll { background-color: #ffffcc }
.codehilite { background: #f8f8f8; }
.codehilite .c { color: #3D7B7B; font-style: italic } /* Comment */
.codehilite .err { border: 1px solid #FF0000 } /* Error */
.codehilite .k { color: #008000; font-weight: bold } /* Keyword */
.codehilite .o { color: #666666 } /* Operator */
.codehilite .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
.codehilite .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
.codehilite .cp { color: #9C6500 } /* Comment.Preproc */
.codehilite .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
.codehilite .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
.codehilite .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
.codehilite .gd { color: #A00000 } /* Generic.Deleted */
.codehilite .ge { font-style: italic } /* Generic.Emph */
.codehilite .gr { color: #E40000 } /* Generic.Error */
.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.codehilite .gi { color: #008400 } /* Generic.Inserted */
.codehilite .go { color: #717171 } /* Generic.Output */
.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.codehilite .gs { font-weight: bold } /* Generic.Strong */
.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.codehilite .gt { color: #0044DD } /* Generic.Traceback */
.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.codehilite .kp { color: #008000 } /* Keyword.Pseudo */
.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.codehilite .kt { color: #B00040 } /* Keyword.Type */
.codehilite .m { color: #666666 } /* Literal.Number */
.codehilite .s { color: #BA2121 } /* Literal.String */
.codehilite .na { color: #687822 } /* Name.Attribute */
.codehilite .nb { color: #008000 } /* Name.Builtin */
.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.codehilite .no { color: #880000 } /* Name.Constant */
.codehilite .nd { color: #AA22FF } /* Name.Decorator */
.codehilite .ni { color: #717171; font-weight: bold } /* Name.Entity */
.codehilite .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
.codehilite .nf { color: #0000FF } /* Name.Function */
.codehilite .nl { color: #767600 } /* Name.Label */
.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */
.codehilite .nv { color: #19177C } /* Name.Variable */
.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.codehilite .w { color: #bbbbbb } /* Text.Whitespace */
.codehilite .mb { color: #666666 } /* Literal.Number.Bin */
.codehilite .mf { color: #666666 } /* Literal.Number.Float */
.codehilite .mh { color: #666666 } /* Literal.Number.Hex */
.codehilite .mi { color: #666666 } /* Literal.Number.Integer */
.codehilite .mo { color: #666666 } /* Literal.Number.Oct */
.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */
.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */
.codehilite .sc { color: #BA2121 } /* Literal.String.Char */
.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */
.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */
.codehilite .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */
.codehilite .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
.codehilite .sx { color: #008000 } /* Literal.String.Other */
.codehilite .sr { color: #A45A77 } /* Literal.String.Regex */
.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */
.codehilite .ss { color: #19177C } /* Literal.String.Symbol */
.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */
.codehilite .fm { color: #0000FF } /* Name.Function.Magic */
.codehilite .vc { color: #19177C } /* Name.Variable.Class */
.codehilite .vg { color: #19177C } /* Name.Variable.Global */
.codehilite .vi { color: #19177C } /* Name.Variable.Instance */
.codehilite .vm { color: #19177C } /* Name.Variable.Magic */
.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */
2 changes: 1 addition & 1 deletion daiquiri/core/assets/scss/base/layout.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
.content {
margin-top: 4rem;
margin-top: 2rem;
}
3 changes: 3 additions & 0 deletions daiquiri/core/assets/scss/base/modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
:last-child {
margin-bottom: 0;
}
img {
width: 100%;
}
}

.modal-separator {
Expand Down
8 changes: 5 additions & 3 deletions daiquiri/metadata/templates/metadata/schema.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ <h2>{% trans 'Tables' %}</h2>

{% for table in tables %}
<div class="card mb-3">
<div class="card-header">
<h5 class="card-header">
<a href="{% url 'metadata:table' schema.name table.name %}">
{% if table.title %}
{{ table.title }} ({{ table }})
{% else %}
{{ table.name }}
{% endif %}
</a>
</div>
</h5>
<div class="card-body">
{% if table.description %}
{{ table.description | markdown }}
Expand All @@ -57,8 +57,10 @@ <h2>{% trans 'Tables' %}</h2>
{% endif %}
</div>
{% if table.doi %}
<div class="card-footer">
<div class="card-footer text-muted">
<small>
DOI: {% doi_link table.doi %}
</small>
</div>
{% endif %}
</div>
Expand Down
8 changes: 5 additions & 3 deletions daiquiri/metadata/templates/metadata/schemas.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ <h1 class="overflow-hidden">
{% block page %}
{% for schema in schemas %}
<div class="card mb-3">
<div class="card-header">
<h5 class="card-header">
<a href="{% url 'metadata:schema' schema.name %}">
{% if schema.title %}
{{ schema.title }} ({{ schema }})
{% else %}
{{ schema }}
{% endif %}
</a>
</div>
</h5>
<div class="card-body">
{% if schema.description %}
{{ schema.description | markdown }}
Expand All @@ -30,8 +30,10 @@ <h1 class="overflow-hidden">
{% endif %}
</div>
{% if schema.doi %}
<div class="card-footer">
<div class="card-footer text-muted">
<small>
DOI: {% doi_link schema.doi %}
</small>
</div>
{% endif %}
</div>
Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ keywords = []
license = {text = "Apache-2.0"}
authors = [
{name = "Jochen Klar", email = "[email protected]"},
{name = "nastasia Galkin", email = "[email protected]"},
{name = "Anastasia Galkin", email = "[email protected]"},
{name = "Yori Fournier", email = "[email protected]"},
{name = "Kirill Makan", email = "[email protected]"},
]
Expand Down Expand Up @@ -55,7 +55,8 @@ dependencies = [
"jsonfield~=3.1.0",
"lunr~=0.6.2",
"Markdown~=3.4.3",
"queryparser-python3~=0.6.1",
"Pygments~=2.15.1",
"queryparser-python3~=0.7",
"rules~=3.3",
"XlsxWriter~=3.1.2",
]
Expand Down

0 comments on commit cc82a7d

Please sign in to comment.