Remove old vue editor

This commit is contained in:
Paul Chavard 2019-03-13 15:32:44 +01:00
parent 51c79ba6a6
commit f5a66df802
5 changed files with 0 additions and 567 deletions

View file

@ -1,254 +0,0 @@
import { getJSON, debounce } from '@utils';
import Uploader from '../../shared/activestorage/uploader';
export default {
props: ['state', 'index', 'item'],
computed: {
isValid() {
if (this.deleted) {
return true;
}
if (this.libelle) {
return !!this.libelle.trim();
}
return false;
},
itemClassName() {
const classNames = [`draggable-item-${this.index}`];
if (this.isHeaderSection) {
classNames.push('type-header-section');
}
return classNames.join(' ');
},
isDropDown() {
return [
'drop_down_list',
'multiple_drop_down_list',
'linked_drop_down_list'
].includes(this.typeChamp);
},
isFile() {
return this.typeChamp === 'piece_justificative';
},
isCarte() {
return this.typeChamp === 'carte';
},
isExplication() {
return this.typeChamp === 'explication';
},
isHeaderSection() {
return this.typeChamp === 'header_section';
},
isRepetition() {
return this.typeChamp === 'repetition';
},
options() {
const options = this.item.options || {};
for (let key of Object.keys(options)) {
options[key] = castBoolean(options[key]);
}
return options;
},
attribute() {
if (this.state.isAnnotation) {
return 'types_de_champ_private_attributes';
} else {
return 'types_de_champ_attributes';
}
},
payload() {
const payload = {
libelle: this.libelle,
type_champ: this.typeChamp,
mandatory: this.mandatory,
description: this.description,
drop_down_list_value: this.dropDownListValue,
order_place: this.index
};
if (this.pieceJustificativeTemplate) {
payload.piece_justificative_template = this.pieceJustificativeTemplate;
}
if (this.state.parentId) {
payload.parent_id = this.state.parentId;
}
if (!this.id && this.state.isAnnotation) {
payload.private = true;
}
Object.assign(payload, this.options);
return payload;
},
saveUrl() {
if (this.id) {
return `${this.state.saveUrl}/${this.id}`;
}
return this.state.saveUrl;
},
savePayload() {
if (this.deleted) {
return {};
}
return { type_de_champ: this.payload };
},
saveMethod() {
if (this.deleted) {
return 'delete';
} else if (this.id) {
return 'patch';
}
return 'post';
},
typesDeChamp() {
return this.item.types_de_champ;
},
typesDeChampOptions() {
return this.state.typesDeChampOptions.filter(
([, typeChamp]) => !EXCLUDE_FROM_REPETITION.includes(typeChamp)
);
},
stateForRepetition() {
return Object.assign({}, this.state, {
typesDeChamp: this.typesDeChamp,
typesDeChampOptions: this.typesDeChampOptions,
prefix: `${this.state.prefix}[${this.attribute}][${this.index}]`,
parentId: this.id
});
}
},
data() {
return {
id: this.item.id,
typeChamp: this.item.type_champ,
libelle: this.item.libelle,
mandatory: this.item.mandatory,
description: this.item.description,
pieceJustificativeTemplate: null,
pieceJustificativeTemplateUrl: this.item.piece_justificative_template_url,
pieceJustificativeTemplateFilename: this.item
.piece_justificative_template_filename,
dropDownListValue: this.item.drop_down_list_value,
deleted: false,
isSaving: false,
isUploading: false,
hasChanges: false
};
},
watch: {
index() {
this.update();
}
},
created() {
this.debouncedSave = debounce(() => this.save(), 500);
this.debouncedUpload = debounce(evt => this.upload(evt), 500);
},
methods: {
removeChamp() {
if (this.id) {
this.deleted = true;
this.debouncedSave();
} else {
const index = this.state.typesDeChamp.indexOf(this.item);
this.state.typesDeChamp.splice(index, 1);
}
},
nameFor(name) {
return `${this.state.prefix}[${this.attribute}][${this.index}][${name}]`;
},
elementIdFor(name) {
const prefix = this.state.prefix.replace(/\[/g, '_').replace(/\]/g, '');
return `${prefix}_${this.attribute}_${this.index}_${name}`;
},
addChamp() {
this.typesDeChamp.push({
type_champ: 'text',
types_de_champ: []
});
},
update() {
this.hasChanges = true;
if (this.isValid) {
if (this.state.inFlight === 0) {
this.state.flash.clear();
}
this.debouncedSave();
}
},
upload(evt) {
if (this.isUploading) {
this.debouncedUpload();
} else {
const input = evt.target;
const file = input.files[0];
if (file) {
this.isUploading = true;
const controller = new Uploader(
input,
file,
this.state.directUploadUrl
);
controller.start().then(signed_id => {
this.pieceJustificativeTemplate = signed_id;
this.isUploading = false;
this.debouncedSave();
});
}
input.value = null;
}
},
save() {
if (this.isSaving) {
this.debouncedSave();
} else {
this.isSaving = true;
this.state.inFlight++;
getJSON(this.saveUrl, this.savePayload, this.saveMethod)
.then(data => {
this.onSuccess(data);
})
.catch(xhr => {
this.onError(xhr);
});
}
},
onSuccess(data) {
if (data && data.type_de_champ) {
this.id = data.type_de_champ.id;
this.pieceJustificativeTemplateUrl =
data.type_de_champ.piece_justificative_template_url;
this.pieceJustificativeTemplateFilename =
data.type_de_champ.piece_justificative_template_filename;
this.pieceJustificativeTemplate = null;
}
this.state.inFlight--;
this.isSaving = false;
this.hasChanges = false;
if (this.state.inFlight === 0) {
this.state.flash.success();
}
},
onError(xhr) {
this.isSaving = false;
this.state.inFlight--;
try {
const {
errors: [message]
} = JSON.parse(xhr.responseText);
this.state.flash.error(message);
} catch (e) {
this.state.flash.error(xhr.responseText);
}
}
}
};
const EXCLUDE_FROM_REPETITION = [
'carte',
'dossier_link',
'repetition',
'siret'
];
function castBoolean(value) {
return value && value != 0;
}

View file

@ -1,181 +0,0 @@
<template>
<div class="deleted" v-if="deleted">
<input type="hidden" :name="nameFor('id')" :value="id">
<input type="hidden" :name="nameFor('_destroy')" value="true">
</div>
<div class="draggable-item flex column justify-start" v-else :class="itemClassName">
<div class="flex justify-start section head" :class="{ hr: !isHeaderSection }">
<div class="handle">
<img :src="state.dragIconUrl" alt="">
</div>
<div class="cell">
<select
:id="elementIdFor('type_champ')"
:name="nameFor('type_champ')"
v-model="typeChamp"
@change="update"
class="small-margin small inline">
<option v-for="option in state.typesDeChampOptions" :key="option[1]" :value="option[1]">
{{ option[0] }}
</option>
</select>
</div>
<div class="flex justify-start delete">
<button class="button danger" @click.prevent="removeChamp">
Supprimer
</button>
</div>
</div>
<div class="flex justify-start section" :class="{ hr: isDropDown || isFile || isCarte }">
<div class="flex column justify-start shift-left">
<div class="cell libelle">
<label :for="elementIdFor('libelle')">
Libellé
</label>
<input
type="text"
:id="elementIdFor('libelle')"
:name="nameFor('libelle')"
v-model="libelle"
@change="update"
class="small-margin small"
:class="{ error: hasChanges && !isValid }">
</div>
<div class="cell" v-show="!isHeaderSection && !isExplication && !state.isAnnotation">
<label :for="elementIdFor('mandatory')">
Obligatoire
</label>
<input :name="nameFor('mandatory')" type="hidden" value="0">
<input
type="checkbox"
:id="elementIdFor('mandatory')"
:name="nameFor('mandatory')"
v-model="mandatory"
@change="update"
class="small-margin small"
value="1">
</div>
</div>
<div class="flex justify-start">
<div class="cell" v-show="!isHeaderSection">
<label :for="elementIdFor('description')">
Description
</label>
<textarea
:id="elementIdFor('description')"
:name="nameFor('description')"
v-model="description"
@change="update"
rows=3
cols=40
class="small-margin small">
</textarea>
</div>
</div>
</div>
<div class="flex justify-start section shift-left" v-show="!isHeaderSection">
<div class="cell" v-show="isDropDown">
<label :for="elementIdFor('drop_down_list')">
Liste déroulante
</label>
<textarea
:id="elementIdFor('drop_down_list')"
:name="nameFor('drop_down_list_attributes[value]')"
v-model="dropDownListValue"
@change="update"
rows=3
cols=40
placeholder="Ecrire une valeur par ligne et --valeur-- pour un séparateur."
class="small-margin small">
</textarea>
</div>
<div class="cell" v-show="isFile">
<label :for="elementIdFor('piece_justificative_template')">
Modèle
</label>
<template v-if="pieceJustificativeTemplateUrl">
<a :href="pieceJustificativeTemplateUrl" rel="noopener" target="_blank">
{{pieceJustificativeTemplateFilename}}
</a>
<br> Modifier :
</template>
<input
type="file"
:id="elementIdFor('piece_justificative_template')"
:name="nameFor('piece_justificative_template')"
@change="upload"
class="small-margin small">
</div>
<div class="cell" v-show="isCarte">
<label>
Utilisation de la cartographie
</label>
<div class="carte-options">
<label :for="elementIdFor('quartiers_prioritaires')">
<input :name="nameFor('quartiers_prioritaires')" type="hidden" value="0">
<input
type="checkbox"
:id="elementIdFor('quartiers_prioritaires')"
:name="nameFor('quartiers_prioritaires')"
v-model="options.quartiers_prioritaires"
@change="update"
class="small-margin small"
value="1">
Quartiers prioritaires
</label>
<label :for="elementIdFor('cadastres')">
<input :name="nameFor('cadastres')" type="hidden" value="0">
<input
type="checkbox"
:id="elementIdFor('cadastres')"
:name="nameFor('cadastres')"
v-model="options.cadastres"
@change="update"
class="small-margin small"
value="1">
Cadastres
</label>
<label :for="elementIdFor('parcelles_agricoles')">
<input :name="nameFor('parcelles_agricoles')" type="hidden" value="0">
<input
type="checkbox"
:id="elementIdFor('parcelles_agricoles')"
:name="nameFor('parcelles_agricoles')"
v-model="options.parcelles_agricoles"
@change="update"
class="small-margin small"
value="1">
Parcelles Agricoles
</label>
</div>
</div>
<div class="flex-grow cell" v-show="isRepetition">
<Draggable :list="typesDeChamp" :options="{handle:'.handle'}">
<DraggableItem
v-for="(item, index) in typesDeChamp"
:state="stateForRepetition"
:index="index"
:item="item"
:key="item.id" />
</Draggable>
<button class="button" @click.prevent="addChamp">
<template v-if="state.isAnnotation">
Ajouter une annotation
</template>
<template v-else>
Ajouter un champ
</template>
</button>
</div>
</div>
<div class="meta">
<input type="hidden" :name="nameFor('order_place')" :value="index">
<input type="hidden" :name="nameFor('id')" :value="id">
</div>
</div>
</template>
<script src="./DraggableItem.js"></script>

View file

@ -1,14 +0,0 @@
export default {
props: ['state', 'version'],
methods: {
addChamp() {
this.state.typesDeChamp.push({
type_champ: 'text',
types_de_champ: []
});
},
save() {
this.state.flash.success();
}
}
};

View file

@ -1,28 +0,0 @@
<template>
<div class="champs-editor">
<Draggable :list="state.typesDeChamp" :options="{handle:'.handle'}">
<DraggableItem
v-for="(item, index) in state.typesDeChamp"
:state="state"
:index="index"
:item="item"
:key="item.id" />
</Draggable>
<div class="footer"></div>
<div class="buttons">
<button class="button" v-scroll-to="'.footer'" @click.prevent="addChamp">
<template v-if="state.isAnnotation">
Ajouter une annotation
</template>
<template v-else>
Ajouter un champ
</template>
</button>
<button class="button primary" @click.prevent="save">Enregistrer</button>
</div>
</div>
</template>
<script src="./DraggableList.js"></script>

View file

@ -1,90 +0,0 @@
import Vue from 'vue';
import Draggable from 'vuedraggable';
import VueScrollTo from 'vue-scrollto';
import DraggableItem from './DraggableItem';
import DraggableList from './DraggableList';
Vue.component('Draggable', Draggable);
Vue.component('DraggableItem', DraggableItem);
Vue.use(VueScrollTo, { duration: 1500, easing: 'ease' });
addEventListener('DOMContentLoaded', () => {
const el = document.querySelector('#champs-editor');
if (el) {
initEditor(el);
}
});
function initEditor(el) {
const { directUploadUrl, dragIconUrl, saveUrl } = el.dataset;
const state = {
typesDeChamp: JSON.parse(el.dataset.typesDeChamp),
typesDeChampOptions: JSON.parse(el.dataset.typesDeChampOptions),
directUploadUrl,
dragIconUrl,
saveUrl,
isAnnotation: el.dataset.type === 'annotation',
prefix: 'procedure',
inFlight: 0,
flash: new Flash()
};
// We add an initial type de champ here if form is empty
if (state.typesDeChamp.length === 0) {
state.typesDeChamp.push({
type_champ: 'text',
types_de_champ: []
});
}
new Vue({
el,
data: {
state
},
render(h) {
return h(DraggableList, {
props: {
state: this.state
}
});
}
});
}
class Flash {
constructor(isAnnotation) {
this.element = document.querySelector('#flash_messages');
this.isAnnotation = isAnnotation;
}
success() {
if (this.isAnnotation) {
this.add('Annotations privées enregistrées.');
} else {
this.add('Formulaire enregistré.');
}
}
error(message) {
this.add(message, true);
}
clear() {
this.element.innerHTML = '';
}
add(message, isError) {
const html = `<div id="flash_message" class="center">
<div class="alert alert-fixed ${
isError ? 'alert-danger' : 'alert-success'
}">
${message}
</div>
</div>`;
this.element.innerHTML = html;
setTimeout(() => {
this.clear();
}, 6000);
}
}