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. 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). 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 ;) You can also use these mapping standards as a pre-set when you create a new Collection.
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!
## Exporting ## 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", "html-to-json": "^0.6.0",
"mdi": "^2.2.43", "mdi": "^2.2.43",
"moment": "^2.22.1", "moment": "^2.22.1",
"node-sass": "^4.8.3", "qs": "^6.5.2",
"qs": "^6.5.1",
"sass-loader": "^7.0.1",
"v-mask": "^1.3.2", "v-mask": "^1.3.2",
"vue": "^2.5.16", "vue": "^2.5.16",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
@ -23,29 +21,29 @@
"vuex": "^3.0.1" "vuex": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "^8.3.0", "autoprefixer": "^8.5.0",
"babel-core": "^6.26.0", "babel-core": "^6.26.3",
"babel-loader": "^7.1.4", "babel-loader": "^7.1.4",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0", "babel-preset-env": "^1.7.0",
"babel-preset-stage-3": "^6.24.1", "babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.1.4", "cross-env": "^5.1.5",
"css-loader": "^0.28.11", "css-loader": "^0.28.11",
"cypress": "^2.1.0", "cypress": "^2.1.0",
"element-theme-chalk": "^2.3.6", "element-theme-chalk": "^2.3.9",
"eslint": "^4.19.1", "eslint": "^4.19.1",
"eslint-loader": "^2.0.0", "eslint-loader": "^2.0.0",
"eslint-plugin-vue": "^4.5.0", "eslint-plugin-vue": "^4.5.0",
"file-loader": "^1.1.11", "file-loader": "^1.1.11",
"postcss-loader": "^2.1.4", "node-sass": "^4.9.0",
"sass-resources-loader": "^1.3.3", "postcss-loader": "^2.1.5",
"sass-loader": "^7.0.1",
"style-loader": "^0.21.0", "style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.5", "uglifyjs-webpack-plugin": "^1.2.5",
"vue-custom-element": "^3.0.4", "vue-custom-element": "^3.0.6",
"vue-loader": "^14.2.2", "vue-loader": "^15.0.11",
"vue-template-compiler": "^2.5.16", "vue-template-compiler": "^2.5.16",
"webpack": "^4.6.0", "webpack": "^4.8.3",
"webpack-cli": "^2.1.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> </b-dropdown>
</div> </div>
</div> </div>
<div class="table-wrapper"> <div class="table-wrapper">
<table <table
:class="{'selectable-table': !isOnTheme }" :class="{'selectable-table': !isOnTheme }"
@ -43,7 +44,7 @@
<!-- Checking list --> <!-- Checking list -->
<th v-if="!isOnTheme"> <th v-if="!isOnTheme">
&nbsp; &nbsp;
<!-- nothing to show on header --> <!-- nothing to show on header for checkboxes -->
</th> </th>
<!-- Displayed Fields --> <!-- Displayed Fields -->
<th <th
@ -54,6 +55,12 @@
:custom-key="column.slug"> :custom-key="column.slug">
<div class="th-wrap">{{ column.name }}</div> <div class="th-wrap">{{ column.name }}</div>
</th> </th>
<th
class="actions-header"
v-if="!isOnTheme">
&nbsp;
<!-- nothing to show on header for actions cell-->
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -132,84 +139,6 @@
</tbody> </tbody>
</table> </table>
</div> </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> </div>
</template> </template>
@ -236,7 +165,6 @@ export default {
this.selectedItems = []; this.selectedItems = [];
for (let i = 0; i < this.items.length; i++) for (let i = 0; i < this.items.length; i++)
this.selectedItems.push(false); this.selectedItems.push(false);
}, },
watch: { watch: {
selectedItems() { selectedItems() {
@ -292,7 +220,6 @@ export default {
}); });
}, },
deleteSelectedItems() { deleteSelectedItems() {
console.log("OI")
this.$dialog.confirm({ this.$dialog.confirm({
message: this.$i18n.get('info_warning_selected_items_delete'), message: this.$i18n.get('info_warning_selected_items_delete'),
onConfirm: () => { onConfirm: () => {
@ -360,46 +287,10 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import "../../scss/_variables.scss"; @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 { .selection-control {
padding: 6px 14px 0px 14px; padding: 6px 14px 0px 14px;
z-index: 9999;
position: relative; position: relative;
background: white; background: white;
height: 40px; height: 40px;
@ -423,7 +314,11 @@ export default {
background-color: white; background-color: white;
border-bottom: 1px solid $tainacan-input-background; border-bottom: 1px solid $tainacan-input-background;
top: 0px; 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) { // &.selectable-table th:nth-child(2), &.selectable-table td:nth-child(2) {
@ -431,31 +326,34 @@ export default {
// } // }
.checkbox-cell { .checkbox-cell {
min-width: 44px;
width: 44px; width: 44px;
height: 58px;
padding: 0; padding: 0;
position: sticky !important; position: sticky !important;
position: -webkit-sticky !important; position: -webkit-sticky !important;
left: 0; left: 0;
top: auto; top: auto;
visibility: hidden; visibility: hidden;
z-index: 9;
&::before { &::before {
box-shadow: inset 53px 0 10px -12px #222; box-shadow: inset 54px 0 10px -12px #222;
content: " "; content: " ";
width: 64px; width: 54px;
height: 100%; height: 100%;
position: absolute; position: absolute;
left: 0; left: 0;
top: 0;
} }
.checkbox { label.checkbox {
border-radius: 0px; border-radius: 0px;
background-color: white; background-color: white;
padding: 10px 10px 10px 14px; padding: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex;
justify-content: center;
} }
&.is-selecting { &.is-selecting {
visibility: visible; visibility: visible;
@ -495,7 +393,7 @@ export default {
} }
td.column-default-width{ td.column-default-width{
max-width: 350px; max-width: 300px;
p { p {
text-overflow: ellipsis; text-overflow: ellipsis;
overflow-x: hidden; overflow-x: hidden;
@ -515,22 +413,27 @@ export default {
td.actions-cell { td.actions-cell {
padding: 0px; padding: 0px;
visibility: hidden;
position: absolute;
right: 8.333333%;
top: auto;
display: none;
position: sticky !important;
position: -webkit-sticky !important;
right: 0px;
top: auto;
width: 8.333333333%;
.actions-container { .actions-container {
visibility: hidden;
display: flex;
position: relative; position: relative;
padding: 10px; padding: 0;
height: 100%; height: 100%;
min-width: 120px;
z-index: 9; z-index: 9;
background-color: $tainacan-input-background; background-color: transparent;
} }
a .icon { a {
margin: 8px; margin: auto;
.mdi {font-size: 18px !important; }
} }
} }
@ -544,16 +447,18 @@ export default {
.checkbox { background-color: $tainacan-input-background; } .checkbox { background-color: $tainacan-input-background; }
} }
.actions-cell { .actions-cell {
visibility: visible; .actions-container {
display: block; visibility: visible;
background: $tainacan-input-background;
}
&::after { &::after {
box-shadow: inset -113px 0 17px -17px #222; box-shadow: inset -134px 0 17px -21px #222;
content: " "; content: " ";
width: 125px; width: 140px;
height: 100%; height: 100%;
position: absolute; position: absolute;
right: 0; right: 0px;
top: 0; top: 0;
} }
} }

View File

@ -3,91 +3,127 @@
<b-loading <b-loading
:active.sync="isLoading" :active.sync="isLoading"
:can-cancel="false"/> :can-cancel="false"/>
<tainacan-title/> <tainacan-title/>
<div class="content">
<router-link <div class="columns">
class="button is-secondary" <div class="column is-4">
:to="{ path: $routerHelper.getItemEditPath(collectionId, itemId)}"> <div class="column is-12">
{{ $i18n.getFrom('items','edit_item') }} <router-link
</router-link> class="button is-secondary"
<a :to="{ path: $routerHelper.getItemEditPath(collectionId, itemId)}">
class="button is-success is-pulled-right" {{ $i18n.getFrom('items','edit_item') }}
:href="item.url"> </router-link>
{{ $i18n.getFrom('items', 'view_item') }} <a
</a> class="button is-success is-pulled-right"
<br> :href="item.url">
{{ $i18n.getFrom('items', 'view_item') }}
</a>
<div <br>
class="card-image" <br>
v-if="item.document">
<figure
class="image"
v-html="item.document_as_html"/>
</div>
<br>
<div <!-- Status -------------------------------- -->
v-if="item.thumbnail" <div class="section-label">
class="media"> <label>{{ $i18n.get('label_status') }}</label>
<figure </div>
class="media-left"> <div>
<p class="image is-128x128"> <p>{{ item.status }}</p>
<img :src="item.thumbnail"> </div>
</p>
</figure>
<div class="media-content">
{{ $i18n.get('label_thumbnail') }}
</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-if="item.document !== undefined && item.document !== null &&
item.document_type !== undefined && item.document_type !== null &&
item.document !== '' && item.document_type !== 'empty'">
<div v-if="item.document_type === 'attachment'">
<div v-html="item.document_as_html"/>
</div>
<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-for="(attachment, index) in attachmentsList"
:key="index">
<span class="tag is-primary">
{{ attachment.title.rendered }}
</span>
</div>
</div>
</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>
<div <!-- Fields -------------------------------- -->
v-for="(metadata, index) in item.metadata" <div>
:key="index" <div
class="box"> v-for="(field, index) of fieldList"
<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>
<div
class="box">
<div
v-if="attachments && attachments.length > 0">
<span
v-for="(attachment, index) in attachments"
:key="index" :key="index"
> class="field">
<a <b-collapse :open="open">
target="blank" <label
:href="attachment.guid.rendered">{{ attachment.guid.rendered }}</a> class="label"
<br> slot="trigger"
</span> 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>
<p v-else>--</p>
<p>
<i>
{{ $i18n.get('label_attachments') }}
</i>
</p>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
@ -101,24 +137,36 @@
return { return {
collectionId: Number, collectionId: Number,
itemId: Number, itemId: Number,
isLoading: false isLoading: false,
open: false,
} }
}, },
methods: { methods: {
...mapActions('item', [ ...mapActions('item', [
'fetchItem', 'fetchItem',
'fetchAttachments' 'fetchAttachments',
'fetchFields',
]), ]),
...mapGetters('item', [ ...mapGetters('item', [
'getItem', 'getItem',
'getFields',
'getAttachments' 'getAttachments'
]), ]),
loadMetadata() {
// Obtains Item Field
this.fetchFields(this.itemId).then(() => {
this.isLoading = false;
});
},
}, },
computed: { computed: {
item() { item() {
return this.getItem(); return this.getItem();
}, },
attachments() { fieldList() {
return JSON.parse(JSON.stringify(this.getFields()));
},
attachmentsList() {
return this.getAttachments(); return this.getAttachments();
} }
}, },
@ -129,11 +177,10 @@
// Puts loading on Item Loading // Puts loading on Item Loading
this.isLoading = true; this.isLoading = true;
let loadingInstance = this;
// Obtains Item // Obtains Item
this.fetchItem(this.itemId).then(() => { this.fetchItem(this.itemId).then(() => {
loadingInstance.isLoading = false; this.loadMetadata();
}); });
// Get attachments // Get attachments
@ -142,3 +189,80 @@
} }
</script> </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; return null;
} }
$imagick = new \Imagick($filepath); $imagick = new \Imagick();
$imagick->setIteratorIndex(0); $imagick->setResolution(72,72);
$imagick->readImage($filepath . '[0]');
//$imagick->setIteratorIndex(0);
$imagick->setImageFormat('jpg'); $imagick->setImageFormat('jpg');
return $imagick->getImageBlob(); return $imagick->getImageBlob();
} }

View File

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

View File

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