Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
fabs balvedi 2018-05-18 16:49:57 -03:00
commit d29e0ac311
8 changed files with 1100 additions and 506 deletions

View File

@ -8,13 +8,11 @@ But sometimes you dont want just to have your collections browsable via web, you
With Tainacan you have the possibility to map your collection structure to one or more known standards you may want to be compatible with. So even if you use a custom set of fields to describe your collection, you may be compatible and interoperate with other repositories.
You do it by informing, for each field you create, what is it relative in each format you want to map your collection to. You may sau for example, that you "Name" Field is the equivalent to the dc:Title attribute in Dublin Core and some another attribute in other format you choose.
You do it by informing, for each field you create, what is it relative in each format you want to map your collection to. You may say for example, that you "Name" Field is the equivalent to the dc:Title attribute in Dublin Core and some another attribute in other format you choose.
Tainacan is shipped with some Mapping standards that implement popular metadata standards. And it will be easy to create new standards. See more [details about mapping standards](mapping-standards.md).
Note: When you use a preset to build your collection, chances are that the mapping is already done. This is a good reason to consider using presets ;)
Note 2: If the mapping standard you mapped your collection to supports it, you will be able to expose your collection en JSON-LD format!
You can also use these mapping standards as a pre-set when you create a new Collection.
## Exporting

1062
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -13,9 +13,7 @@
"html-to-json": "^0.6.0",
"mdi": "^2.2.43",
"moment": "^2.22.1",
"node-sass": "^4.8.3",
"qs": "^6.5.1",
"sass-loader": "^7.0.1",
"qs": "^6.5.2",
"v-mask": "^1.3.2",
"vue": "^2.5.16",
"vue-router": "^3.0.1",
@ -23,29 +21,29 @@
"vuex": "^3.0.1"
},
"devDependencies": {
"autoprefixer": "^8.3.0",
"babel-core": "^6.26.0",
"autoprefixer": "^8.5.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.1.4",
"cross-env": "^5.1.5",
"css-loader": "^0.28.11",
"cypress": "^2.1.0",
"element-theme-chalk": "^2.3.6",
"element-theme-chalk": "^2.3.9",
"eslint": "^4.19.1",
"eslint-loader": "^2.0.0",
"eslint-plugin-vue": "^4.5.0",
"file-loader": "^1.1.11",
"postcss-loader": "^2.1.4",
"sass-resources-loader": "^1.3.3",
"node-sass": "^4.9.0",
"postcss-loader": "^2.1.5",
"sass-loader": "^7.0.1",
"style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.5",
"vue-custom-element": "^3.0.4",
"vue-loader": "^14.2.2",
"vue-custom-element": "^3.0.6",
"vue-loader": "^15.0.11",
"vue-template-compiler": "^2.5.16",
"webpack": "^4.6.0",
"webpack": "^4.8.3",
"webpack-cli": "^2.1.3",
"webpack-dev-server": "^3.1.3"
"webpack-dev-server": "^3.1.4"
}
}

View File

@ -34,6 +34,7 @@
</b-dropdown>
</div>
</div>
<div class="table-wrapper">
<table
:class="{'selectable-table': !isOnTheme }"
@ -43,7 +44,7 @@
<!-- Checking list -->
<th v-if="!isOnTheme">
&nbsp;
<!-- nothing to show on header -->
<!-- nothing to show on header for checkboxes -->
</th>
<!-- Displayed Fields -->
<th
@ -54,6 +55,12 @@
:custom-key="column.slug">
<div class="th-wrap">{{ column.name }}</div>
</th>
<th
class="actions-header"
v-if="!isOnTheme">
&nbsp;
<!-- nothing to show on header for actions cell-->
</th>
</tr>
</thead>
<tbody>
@ -132,84 +139,6 @@
</tbody>
</table>
</div>
<!--
<b-table
ref="itemsTable"
:data="items"
@selection-change="handleSelectionChange"
:checked-rows.sync="selectedItems"
:checkable="!isOnTheme"
:loading="isLoading"
hoverable
:selectable="!isOnTheme"
backend-sorting>
<template slot-scope="props">
<b-table-column
v-for="(column, index) in tableFields"
v-if="column.field != 'row_actions' || (column.field == 'row_actions' && props.row.current_user_can_edit && !isOnTheme)"
:key="index"
:custom-key="column.slug"
:label="column.name"
:visible="column.display"
:class="column.field == 'row_creation' ? 'row-creation' : ''"
:width="column.field == 'row_actions' ? 78 : column.field == 'row_thumbnail' ? 55 : undefined ">
<template v-if="column.field != 'row_thumbnail' && column.field != 'row_actions' && column.field != 'row_creation'">
<span
class="clickable-row"
v-if="!isOnTheme && props.row.metadata[column.slug].value_as_html == props.row.metadata[column.slug].value_as_string"
@click.prevent="goToItemPage(props.row.id)"
v-html="renderMetadata( props.row.metadata[column.slug] )" />
<span
class="clickable-row"
v-if="!isOnTheme && props.row.metadata[column.slug].value_as_html != props.row.metadata[column.slug].value_as_string"
v-html="renderMetadata( props.row.metadata[column.slug] )" />
<a
v-if="isOnTheme"
:href="getDecodedURI(props.row.url)"
v-html="renderMetadata( props.row.metadata[column.slug] )" />
</template>
<template v-if="column.field == 'row_thumbnail'">
<router-link
tag="img"
class="table-thumb clickable-row"
:to="{path: $routerHelper.getItemPath(collectionId, props.row.id)}"
:src="props.row[column.slug]"/>
</template>
<template
class="row-creation"
v-if="column.field == 'row_creation'">
<router-link
class="clickable-row"
v-html="getCreationHtml(props.row)"
tag="span"
:to="{path: $routerHelper.getItemPath(collectionId, props.row.id)}"/>
</template>
<template v-if="column.field == 'row_actions'">
<a
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click="goToItemEditPage(props.row.id)">
<b-icon
type="is-gray"
icon="pencil"/></a>
<a
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click="deleteOneItem(props.row.id)">
<b-icon
type="is-gray"
icon="delete"/></a>
</template>
</b-table-column>
</template>
</b-table>
-->
</div>
</template>
@ -236,7 +165,6 @@ export default {
this.selectedItems = [];
for (let i = 0; i < this.items.length; i++)
this.selectedItems.push(false);
},
watch: {
selectedItems() {
@ -292,7 +220,6 @@ export default {
});
},
deleteSelectedItems() {
console.log("OI")
this.$dialog.confirm({
message: this.$i18n.get('info_warning_selected_items_delete'),
onConfirm: () => {
@ -360,46 +287,10 @@ export default {
<style lang="scss" scoped>
@import "../../scss/_variables.scss";
.table-test{
height: 240px;
th {
position: -webkit-sticky; // for safari
position: sticky;
top: 0; left: 0;
background: #ddd !important;
color: black;
white-space: nowrap;
&:first-child {
z-index: 3 !important;
}
}
tr:hover td:first-child{
visibility: visible;
}
th, td {
padding: 10px 100px;
text-transform: capitalize;
&:first-child {
visibility: hidden;
position: -webkit-sticky; // for safari
position: sticky;
background-color: #eee;
left: 0px;
z-index: 2;
width: 200px;
}
}
}
.selection-control {
padding: 6px 14px 0px 14px;
z-index: 9999;
position: relative;
background: white;
height: 40px;
@ -423,7 +314,11 @@ export default {
background-color: white;
border-bottom: 1px solid $tainacan-input-background;
top: 0px;
z-index: 99999
z-index: 9;
&.actions-header {
min-width: 8.333333333%;
}
}
// &.selectable-table th:nth-child(2), &.selectable-table td:nth-child(2) {
@ -431,31 +326,34 @@ export default {
// }
.checkbox-cell {
min-width: 44px;
width: 44px;
height: 58px;
padding: 0;
position: sticky !important;
position: -webkit-sticky !important;
left: 0;
top: auto;
visibility: hidden;
z-index: 9;
&::before {
box-shadow: inset 53px 0 10px -12px #222;
box-shadow: inset 54px 0 10px -12px #222;
content: " ";
width: 64px;
width: 54px;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.checkbox {
label.checkbox {
border-radius: 0px;
background-color: white;
padding: 10px 10px 10px 14px;
padding: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
}
&.is-selecting {
visibility: visible;
@ -495,7 +393,7 @@ export default {
}
td.column-default-width{
max-width: 350px;
max-width: 300px;
p {
text-overflow: ellipsis;
overflow-x: hidden;
@ -515,22 +413,27 @@ export default {
td.actions-cell {
padding: 0px;
visibility: hidden;
position: absolute;
right: 8.333333%;
position: sticky !important;
position: -webkit-sticky !important;
right: 0px;
top: auto;
display: none;
width: 8.333333333%;
.actions-container {
visibility: hidden;
display: flex;
position: relative;
padding: 10px;
padding: 0;
height: 100%;
min-width: 120px;
z-index: 9;
background-color: $tainacan-input-background;
background-color: transparent;
}
a .icon {
margin: 8px;
a {
margin: auto;
.mdi {font-size: 18px !important; }
}
}
@ -544,16 +447,18 @@ export default {
.checkbox { background-color: $tainacan-input-background; }
}
.actions-cell {
.actions-container {
visibility: visible;
display: block;
background: $tainacan-input-background;
}
&::after {
box-shadow: inset -113px 0 17px -17px #222;
box-shadow: inset -134px 0 17px -21px #222;
content: " ";
width: 125px;
width: 140px;
height: 100%;
position: absolute;
right: 0;
right: 0px;
top: 0;
}
}

View File

@ -3,9 +3,12 @@
<b-loading
:active.sync="isLoading"
:can-cancel="false"/>
<tainacan-title/>
<div class="content">
<tainacan-title/>
<div class="columns">
<div class="column is-4">
<div class="column is-12">
<router-link
class="button is-secondary"
:to="{ path: $routerHelper.getItemEditPath(collectionId, itemId)}">
@ -16,79 +19,112 @@
:href="item.url">
{{ $i18n.getFrom('items', 'view_item') }}
</a>
<br>
<br>
<div
class="card-image"
v-if="item.document">
<figure
class="image"
v-html="item.document_as_html"/>
<!-- Status -------------------------------- -->
<div class="section-label">
<label>{{ $i18n.get('label_status') }}</label>
</div>
<br>
<div
v-if="item.thumbnail"
class="media">
<figure
class="media-left">
<p class="image is-128x128">
<img :src="item.thumbnail">
</p>
</figure>
<div class="media-content">
{{ $i18n.get('label_thumbnail') }}
<div>
<p>{{ item.status }}</p>
</div>
</div>
<div class="column is-12">
<!-- Document -------------------------------- -->
<div class="section-label">
<label>{{ item.document !== undefined && item.document !== null && item.document !== '' ?
$i18n.get('label_document') : $i18n.get('label_document_empty') }}</label>
</div>
<div class="section-box">
<div
v-for="(metadata, index) in item.metadata"
:key="index"
class="box">
v-if="item.document !== undefined && item.document !== null &&
item.document_type !== undefined && item.document_type !== null &&
item.document !== '' && item.document_type !== 'empty'">
<p
v-if="metadata.date_i18n"
class="is-size-3"
v-html="metadata.date_i18n"/>
<p
v-else-if="metadata.value_as_html"
class="is-size-3"
v-html="metadata.value_as_html"/>
<p
v-else>--</p>
<p>
<i>
{{ metadata.name }}
</i>
</p>
<div v-if="item.document_type === 'attachment'">
<div v-html="item.document_as_html"/>
</div>
<div
class="box">
<div v-else-if="item.document_type === 'text'">
<div v-html="item.document_as_html"/>
</div>
<div v-else-if="item.document_type === 'url'">
<div v-html="item.document_as_html"/>
</div>
</div>
</div>
</div>
<div class="column is-12">
<!-- Attachments ----------------------------- -->
<div class="section-label">
<label>{{ $i18n.get('label_attachments') }}</label>
</div>
<div class="section-box">
<div class="uploaded-files">
<div
v-if="attachments && attachments.length > 0">
<span
v-for="(attachment, index) in attachments"
:key="index"
>
<a
target="blank"
:href="attachment.guid.rendered">{{ attachment.guid.rendered }}</a>
<br>
v-for="(attachment, index) in attachmentsList"
:key="index">
<span class="tag is-primary">
{{ attachment.title.rendered }}
</span>
</div>
<p v-else>--</p>
<p>
<i>
{{ $i18n.get('label_attachments') }}
</i>
</p>
</div>
</div>
</div>
</div>
<div class="column is-1" />
<div class="column is-7">
<label class="section-label">{{ $i18n.get('fields') }}</label>
<br>
<a
class="collapse-all"
@click="open = !open">
{{ open ? $i18n.get('label_collapse_all') : $i18n.get('label_expand_all') }}
<b-icon
type="is-secondary"
:icon=" open ? 'menu-down' : 'menu-right'"/>
</a>
<!-- Fields -------------------------------- -->
<div>
<div
v-for="(field, index) of fieldList"
:key="index"
class="field">
<b-collapse :open="open">
<label
class="label"
slot="trigger"
slot-scope="props">
<b-icon
type="is-secondary"
:icon="props.open ? 'menu-down' : 'menu-right'"
/>
{{ field.field.name }}
</label>
<div
v-if="field.date_i18n"
class="notification">
<div v-html="field.date_i18n"/>
</div>
<div
v-else
class="notification">
<div v-html="field.value_as_html"/>
</div>
</b-collapse>
</div>
</div>
</div>
</div>
</div>
</template>
@ -101,24 +137,36 @@
return {
collectionId: Number,
itemId: Number,
isLoading: false
isLoading: false,
open: false,
}
},
methods: {
...mapActions('item', [
'fetchItem',
'fetchAttachments'
'fetchAttachments',
'fetchFields',
]),
...mapGetters('item', [
'getItem',
'getFields',
'getAttachments'
]),
loadMetadata() {
// Obtains Item Field
this.fetchFields(this.itemId).then(() => {
this.isLoading = false;
});
},
},
computed: {
item() {
return this.getItem();
},
attachments() {
fieldList() {
return JSON.parse(JSON.stringify(this.getFields()));
},
attachmentsList() {
return this.getAttachments();
}
},
@ -129,11 +177,10 @@
// Puts loading on Item Loading
this.isLoading = true;
let loadingInstance = this;
// Obtains Item
this.fetchItem(this.itemId).then(() => {
loadingInstance.isLoading = false;
this.loadMetadata();
});
// Get attachments
@ -142,3 +189,80 @@
}
</script>
<style lang="scss" scoped>
@import '../../scss/_variables.scss';
.page-container {
height: calc(100% - 82px);
}
.columns > .column {
padding: 0;
}
.field {
border-bottom: 1px solid $draggable-border-color;
padding: 10px 25px;
.label {
font-size: 14px;
font-weight: 500;
margin-bottom: 0.5em;
span {
margin-right: 18px;
}
}
}
.section-label {
position: relative;
label {
font-size: 16px !important;
font-weight: 500 !important;
color: $tertiary !important;
line-height: 1.2em;
}
}
.collapse-all {
font-size: 12px;
.icon {
vertical-align: bottom;
}
}
.section-box {
border: 1px solid $draggable-border-color;
padding: 30px;
margin-top: 16px;
margin-bottom: 38px;
ul {
display: flex;
justify-content: space-evenly;
li {
text-align: center;
button {
border-radius: 50px;
height: 72px;
width: 72px;
border: none;
background-color: $tainacan-input-background;
color: $secondary;
margin-bottom: 6px;
&:hover {
background-color: $primary-light;
cursor: pointer;
}
}
p {
color: $secondary;
}
}
}
}
</style>

View File

@ -109,8 +109,10 @@ class Media {
return null;
}
$imagick = new \Imagick($filepath);
$imagick->setIteratorIndex(0);
$imagick = new \Imagick();
$imagick->setResolution(72,72);
$imagick->readImage($filepath . '[0]');
//$imagick->setIteratorIndex(0);
$imagick->setImageFormat('jpg');
return $imagick->getImageBlob();
}

View File

@ -40,11 +40,7 @@
mixins: [ dateInter ],
created(){
if( this.value ){
let prep = new Date(this.value.replace(/-/g, '/')).toLocaleDateString();
console.log(prep);
this.dateValue = prep;
this.dateValue = new Date(this.value.replace(/-/g, '/')).toLocaleDateString();
}
},
data() {

View File

@ -1,5 +1,6 @@
let path = require('path');
let webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
entry: {
@ -38,14 +39,28 @@ module.exports = {
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],
use: [
'vue-style-loader',
'css-loader',
'postcss-loader',
],
},
{
test: /\.scss$/,
loader: 'sass-resources-loader',
test: /\.s[ac]ss$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader',
options: {
resources: path.resolve(__dirname, './src/admin/scss/_variables.scss')
includePaths: [path.resolve(__dirname, './src/admin/scss/_variables.scss')]
}
},
],
}
]
@ -84,7 +99,8 @@ if (production === true) {
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
}),
new VueLoaderPlugin(),
]);
module.exports.resolve = {
@ -103,6 +119,7 @@ if (production === true) {
NODE_ENV: JSON.stringify('development')
},
}),
new VueLoaderPlugin(),
];
module.exports.resolve = {