Commit 7e47f089 authored by Jean Rabreau's avatar Jean Rabreau
Browse files

馃敄Merge branch 'release/2.0.0'

parents b4d09792 259fd527
Pipeline #68344 failed with stages
in 1 minute and 52 seconds
NODE_ENV=test
NODE_OPTIONS=--openssl-legacy-provider
VUE_APP_NAME=pount
VUE_APP_LOGO=https://gitlab.com/uploads/-/system/project/avatar/18299282/pount-front-neunoeuil.png
VUE_APP_AXIOS_BASE_URL=http://localhost:8000/api/
......@@ -3,7 +3,7 @@ module.exports = {
env: {
node: true
},
'extends': [
extends: [
'plugin:vue/essential',
'eslint:recommended'
],
......
This diff is collapsed.
......@@ -18,7 +18,7 @@
"https://medium.com/sapioit/why-having-3-numbers-in-the-version-name-is-bad-92fc1f6bc73c",
"https://gist.github.com/jashkenas/cbd2b088e20279ae2c8e"
],
"version": "1.0.3",
"version": "2.0.0",
"@comment private": [
"This whole project is just documentation.",
"Don't publish it in npm as is."
......@@ -88,10 +88,10 @@
]
},
"dependencies": {
"@sentry/browser": "^6.13.2",
"@sentry/integrations": "^6.13.2",
"@vue-unistra/formbuilder": "^3.0.19",
"axios": "^0.21.4",
"@sentry/browser": "^6.16.1",
"@sentry/integrations": "^6.16.1",
"@vue-unistra/formbuilder": "^3.0.26",
"axios": "^0.24.0",
"core-js": "^3.18.1",
"hammerjs": "^2.0.8",
"jdenticon": "^3.1.1",
......@@ -102,9 +102,9 @@
"vue": "^2.6.14",
"vue-i18n": "^8.26.5",
"vue-matomo": "^4.1.0",
"vue-router": "^3.5.2",
"vue-router": "^3.5.3",
"vuejs-logger": "^1.5.5",
"vuetify": "^2.5.9",
"vuetify": "^2.6.1",
"vuex": "^3.6.2"
},
"@comment devDependencies": {
......@@ -195,28 +195,27 @@
]
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.13",
"@vue/cli-plugin-e2e-nightwatch": "^4.5.13",
"@vue/cli-plugin-eslint": "^4.5.13",
"@vue/cli-plugin-unit-mocha": "^4.5.13",
"@vue/cli-plugin-vuex": "^4.5.13",
"@vue/cli-service": "^4.5.13",
"@vue/test-utils": "^1.2.2",
"@vue/cli-plugin-babel": "^4.5.15",
"@vue/cli-plugin-e2e-nightwatch": "^4.5.15",
"@vue/cli-plugin-eslint": "^4.5.15",
"@vue/cli-plugin-unit-mocha": "^4.5.15",
"@vue/cli-plugin-vuex": "^4.5.15",
"@vue/cli-service": "^4.5.15",
"@vue/test-utils": "^1.3.0",
"babel-eslint": "^10.0.3",
"babel-plugin-istanbul": "^6.0.0",
"chai": "^4.3.4",
"chromedriver": "^93.0.1",
"chromedriver": "^94.0.0",
"eslint": "^6.8.0",
"eslint-plugin-vue": "^7.18.0",
"geckodriver": "^2.0.4",
"jwt-simple": "^0.5.6",
"moxios": "^0.4.0",
"null-loader": "^4.0.1",
"nyc": "^15.1.0",
"sass": "~1.32.13",
"sass-loader": "~10.2.0",
"sinon": "^11.1.2",
"vue-cli-plugin-vuetify": "^2.4.2",
"sinon": "^12.0.1",
"vue-cli-plugin-vuetify": "^2.4.5",
"vue-template-compiler": "^2.6.14",
"vuetify-loader": "^1.7.3",
"webpack-bundle-analyzer": "^4.4.2"
......
......@@ -2961,11 +2961,11 @@ createEntity : function (eName, type, verticesList) {
nEntity.zOff = 0.0;
let modelDescriptor = {};
if(type == "points")
if(type === "points")
modelDescriptor.primitives = ["points"];
else if(type == "lines")
else if(type === "lines")
modelDescriptor.primitives = ["lines"];
else if(type == "triangles")
else if(type === "triangles")
modelDescriptor.primitives = ["triangles"];
modelDescriptor.vertices = {};
modelDescriptor.vertices.position = [];
......@@ -4163,32 +4163,34 @@ isInstanceLightingEnabled : function (tag) {
return Lighting;
},
init3dhop: function() {
this._isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
resizeCanvas: function() {
if (!this._resizable) return;
window.addEventListener('resize', () => {
if (!this._resizable) return;
const canvas = document.getElementById('draw-canvas')
const hop = document.getElementById('hop__container')
const canvas = document.getElementById('draw-canvas')
const hop = document.getElementById('hop__container')
let width, height;
if(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
width = Math.max(document.documentElement.clientWidth, window.innerWidth);
height = window.innerHeight;
}
else {
width = hop.offsetWidth
height = hop.offsetHeight
}
canvas.setAttribute('width', width)
canvas.setAttribute('height', height)
hop.style.width = width
hop.style.height = height
let width, height;
if(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
width = Math.max(document.documentElement.clientWidth, window.innerWidth);
height = window.innerHeight;
}
else {
width = hop.offsetWidth
height = hop.offsetHeight
}
canvas.setAttribute('width', width)
canvas.setAttribute('height', height)
hop.style.width = width
hop.style.height = height
this.ui.postDrawEvent();
},
this.ui.postDrawEvent();
});
init3dhop: function() {
this._isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
const resizeEvent = this.resizeCanvas.bind(this)
window.addEventListener('resize', resizeEvent);
const canvas = document.getElementById('draw-canvas')
const hop = canvas.parentElement
......@@ -4199,6 +4201,7 @@ init3dhop: function() {
canvas.setAttribute('height', offsetHeight)
hop.style.width = offsetWidth
hop.style.height = offsetHeight
return resizeEvent
},
// fullscreen mode
......
......@@ -15984,12 +15984,12 @@ SpiderGL.UserInterface.CanvasHandler = function (gl, handler, options) {
/** @private */
const handleMessage = function (evt) {
if (evt.source != window) return;
if (evt.data == SpiderGL.UserInterface.CanvasHandler._FAST_ANIMATE_MESSAGE_NAME) {
if (evt.source !== window) return;
if (evt.data === SpiderGL.UserInterface.CanvasHandler._FAST_ANIMATE_MESSAGE_NAME) {
evt.stopPropagation();
that._onAnimate();
}
else if (evt.data == SpiderGL.UserInterface.CanvasHandler._FAST_DRAW_MESSAGE_NAME) {
else if (evt.data === SpiderGL.UserInterface.CanvasHandler._FAST_DRAW_MESSAGE_NAME) {
evt.stopPropagation();
that._onDraw();
}
......
......@@ -14,6 +14,11 @@
v-else
v-html="identicon"
/>
<v-icon v-if="isPublic"
color="primary"
>
mdi-eye
</v-icon>
</v-avatar>
</template>
......@@ -28,6 +33,10 @@ export default {
size: {
type: Number,
default: 48
},
isPublic: {
type: Boolean,
default: false
}
},
computed: {
......@@ -38,3 +47,28 @@ export default {
}
</script>
<style lang="scss" scoped>
.v-avatar {
position: relative;
overflow: visible;
i {
position: absolute;
top: -8px;
left: -10px;
&:before {
position: absolute;
text-align: center;
line-height: 16px;
height: 16px;
top: 2px;
left: 0;
border-radius: 90%;
background-color: rgba(255,255,255,0.9);
}
&.theme--dark:before {
background-color: rgba(26,26,26,0.8);
}
}
}
</style>
<template>
<div class="mt-2">
<v-toolbar
v-if="canEdit"
flat
>
<v-toolbar-title>{{ $t(`${itemType}.detail`) }}</v-toolbar-title>
<v-spacer />
<v-btn
tile
elevation="0"
color="secondary"
:to="{name: `${itemType}Edit`}"
>
{{ $t('edit') }}
</v-btn>
</v-toolbar>
<v-sheet class="pl-3 text-justify">
<v-subheader>{{ visibility }}</v-subheader>
<v-subheader> {{ $t(`${itemType}.description`) }}</v-subheader>
<div class="description" v-html="item.description" />
</v-sheet>
</div>
</template>
<script>
export default {
name: "DetailView",
props: {
itemType: {
type: String,
required: true
},
canEdit: {
type: Boolean,
default: false
}
},
computed: {
item() {
return this.$store.getters[`${this.itemType}/current`]
},
visibility() {
return this.$t(`visibility.${this.item.isPublic ? 'public' : 'restricted'}`)
},
},
}
</script>
<style lang="scss" scoped>
.description {
padding-left: 2rem;
}
</style>
......@@ -9,6 +9,7 @@
:name="title"
:image="thumbnail"
:size="64"
:is-public="publicIcon"
/>
<div class="d-flex flex-column">
<v-card-title>
......@@ -117,9 +118,19 @@ export default {
required: false,
default: false,
},
publicIcon: {
type: Boolean,
default: false
}
},
components: {
Avatar,
},
};
</script>
<style lang="scss" scoped>
.v-card__subtitle i {
vertical-align: text-bottom;
}
</style>
......@@ -6,13 +6,15 @@
<v-toolbar-title>{{ title }}</v-toolbar-title>
<v-spacer />
<v-btn
v-if="button.isDisplayed"
v-for="button in buttons"
:key="button.label"
tile
elevation="0"
color="secondary"
:to="button.to"
class="mr-2"
v-bind="button"
>
{{ button.text }}
{{ button.label }}
</v-btn>
</v-toolbar>
<v-divider />
......@@ -45,13 +47,14 @@
<div class="d-flex pa-2">
<div
class="d-flex flex-grow-1"
:class="item.to && item.to.length ? 'pointer': ''"
@click="item.to && item.to.length ? $router.push(item.to) : undefined"
:class="item.to ? 'pointer': ''"
@click="item.to ? $router.push(item.to) : undefined"
>
<div class="align-self-center mr-4">
<avatar
:name="item.name"
:image="item.thumbnail"
:is-public="item.isPublic"
/>
</div>
<div class="d-flex flex-grow-1 flex-column flex-lg-row">
......@@ -143,9 +146,9 @@ export default {
type: String,
required: true,
},
button: {
type: Object,
required: true,
buttons: {
type: Array,
default: () => [],
},
items: {
type: Array,
......
<template>
<v-row class="flex-column">
<v-col>
<Visibility :is-public.sync="item.isPublic"/>
</v-col>
<v-col>
<rich-text
:label="$t('item.description')"
v-model="item.description"
/>
</v-col>
<v-col>
<Visibility :is-public.sync="item.isPublic"/>
</v-col>
</v-row>
</template>
......
<template>
<usf-renderer
ref="itemFormMetadata"
:fields="template.fields"
:messages="template.messages"
:submitted-data="submittedData"
:isSubmitButtonDisplayed="false"
/>
</template>
<script>
import MetaSaveMixin from '@/mixins/MetaSaveMixin';
export default {
name: 'ItemFormMetadata',
props: {
template: {
type: Object,
required: true,
},
metaData: {
type: Array,
required: false,
default: () => ([]),
},
},
mixins: [
MetaSaveMixin,
],
data: function() {
return {
item: {
metadata: this.metaData,
},
};
},
computed: {
submittedData() {
return this.toFormData(this.item.metadata);
},
},
methods: {
validate() {
if(this.$refs.itemFormMetadata.$refs.form.validate()) {
const { title } = this.getState;
this.item = {
...this.item,
title: title,
metadata: this.metadata,
viewer: {},
};
return 100;
}
return 0;
},
},
};
</script>
<template>
<v-row class="flex-column">
<v-col>
<section>
<component :is="isCreation ? 'h2' : 'h3'">
{{ title }}
</component>
<v-form ref="details">
<v-text-field
:label="$t('form.field.name')"
v-model="project.name"
:rules="requiredField"
:label="$t('form.field.name')"
v-model="project.name"
:rules="requiredField"
/>
</v-col>
<v-col>
<Visibility :is-public.sync="project.isPublic" />
<rich-text
:label="$t('form.field.description')"
v-model="project.description"
:rules="requiredField"
:label="$t('form.field.description')"
v-model="project.description"
:rules="requiredField"
/>
</v-col>
<v-col>
<Visibility :is-public.sync="project.isPublic" />
</v-col>
</v-row>
<v-row>
<v-col class="d-flex">
<v-spacer />
<v-btn v-if="isCreation"
tile
elevation="0"
color="secondary"
:to="{name: 'dashboard'}"
>
{{ $t('btn.cancel') }}
</v-btn>
<v-btn
tile
elevation="0"
color="primary"
@click="onSubmit"
>
{{ $t('btn.validate') }}
</v-btn>
</v-col>
</v-row>
</v-form>
</section>
</template>
<script>
......@@ -28,19 +48,8 @@ import Visibility from '@/components/common/Visibility'
export default {
name: 'ProjectForm',
props: {
name: {
type: String,
required: false,
default: '',
},
description: {
type: String,
required: false,
default: '',
},
isPublic: {
isCreation: {
type: Boolean,
required: false,
default: false,
},
},
......@@ -54,11 +63,53 @@ export default {
data: function() {
return {
project: {
name: this.name,
description: this.description,
isPublic: this.isPublic,
name: '',
description: '',
isPublic: false,
},
};
},
computed: {
isEdition() {
return !this.isCreation
},
title() {
return this.isEdition
? this.$t('project.generalInfo.label')
: this.$t('project.create')
}
},
created() {
if (this.isEdition) {
const { name, description, isPublic, id } = this.$store.getters['project/current']
this.project = { name, description, isPublic, id }
}
},
methods: {
async onSubmit() {
if(this.$refs.details.validate()) {
const action = `project/${this.isEdition ? 'update' : 'create'}Project`
await this.$store.dispatch(action, this.project)
if (this.isCreation) {
this.$router.push({
name: `projectDetail`,
params: { projectId: this.$store.getters['project/projectId'] }
});
}
}
},
}
};
</script>
<style lang="scss" scoped>
h2 {
margin: 1rem 0 0 1rem;
}
form {
padding: 1rem;
a {
margin-right: 0.5rem;
}
}
</style>
<template>
<v-sheet
class="mt-2"
>
<v-toolbar flat class="flex-grow-0">
<v-toolbar-title>
{{ $t('item.file') }}
</v-toolbar-title>