First EditorJS implementation

This commit is contained in:
Florian Sylvain
2022-12-30 19:30:23 +01:00
parent 80b1364486
commit 44ae2ef43f
8 changed files with 639 additions and 165 deletions
+30 -9
View File
@@ -34,18 +34,39 @@ h1 {
font-family: 'Frank Ruhl Libre', serif;
font-size: 40px;
}
h2 { font-size: 32px; }
h3 { font-size: 24px; }
h4 { font-size: 18px; }
h2, h3, h4, h5, h6 {
h2 {
font-size: 32px;
}
h3 {
font-size: 24px;
}
h4 {
font-size: 18px;
}
h2,
h3,
h4,
h5,
h6 {
font-family: 'Nunito', sans-serif;
}
* {
box-sizing: border-box;
}
p,
a,
input,
label,
button,
span {
font-family: 'Hind', sans-serif;
color: var(--neutral-dark);
box-sizing: border-box;
}
.label-input,
@@ -89,13 +110,13 @@ h2, h3, h4, h5, h6 {
.button-disabled {
border-radius: var(--radius);
border: none;
padding: 3px 16px;
font-size: var(--font-body);
font-weight: var(--medium-weight);
background-color: var(--primary);
transition: background-color 150ms;
cursor: pointer;
@@ -0,0 +1,28 @@
{
"time": 1672423262433,
"blocks": [
{
"id": "SsMzvSlYdr",
"type": "Header",
"data": {
"text": "Bienvenue sur l'éditeur d'article !",
"level": 2
}
},
{
"id": "SCdiyR3ZLh",
"type": "paragraph",
"data": {
"text": "<b>Ici</b>, vous pouvez <u class=\"cdx-underline\">créer</u> votre <i>article</i>."
}
},
{
"id": "PYzhBNCoxo",
"type": "paragraph",
"data": {
"text": "Supprimez ces blocks pour commencer.<br>"
}
}
],
"version": "2.26.4"
}
@@ -0,0 +1,69 @@
{
"messages": {
"ui": {
"blockTunes": {
"toggler": {
"Click to tune": "Cliquez pour régler",
"or drag to move": "ou glissez pour déplacer"
}
},
"inlineToolbar": {
"converter": {
"Convert to": "Convertir en"
}
},
"toolbar": {
"toolbox": {
"Add": "Ajouter"
}
}
},
"toolNames": {
"Text": "Paragraphe",
"Heading": "Titre",
"List": "Liste",
"Warning": "Avertissement",
"Checklist": "Checklist",
"Quote": "Citation",
"Code": "Code",
"Delimiter": "Délimiteur",
"Table": "Tableau",
"Link": "Lien",
"Marker": "Surligner",
"Bold": "Gras",
"Italic": "Italique",
"Underline": "Sousligner"
},
"tools": {
"Header": {
"Heading 1": "Titre 1",
"Heading 2": "Titre 2",
"Heading 3": "Titre 3",
"Heading 4": "Titre 4",
"Heading 5": "Titre 5",
"Heading 6": "Titre 6"
},
"Warning": {
"Title": "Titre",
"Message": "Message"
},
"stub": {
"The block can not be displayed correctly.": "Le block ne peut pas être affiché correctement :(."
},
"Code": {
"Enter a code": "Entrez votre code"
}
},
"blockTunes": {
"delete": {
"Delete": "Supprimer"
},
"moveUp": {
"Move up": "Vers le haut"
},
"moveDown": {
"Move down": "Vers le bas"
}
}
}
}
+83
View File
@@ -0,0 +1,83 @@
<script setup lang="ts">
import i18n from "@/assets/editor_translation.json";
import defaultData from '@/assets/editor_default_content.json'
import EditorJS, { type EditorConfig, type OutputData } from "@editorjs/editorjs";
import Header from "@editorjs/header";
import List from "@editorjs/list";
import NestedList from "@editorjs/nested-list";
import CheckList from "@editorjs/checklist";
import Quote from "@editorjs/quote";
import Warning from "@editorjs/warning";
import Marker from "@editorjs/marker";
import Code from "@editorjs/code";
import Table from "@editorjs/table";
import Underline from "@editorjs/underline";
import Delimiter from "@editorjs/delimiter";
const props = defineProps<{
showDefaultData: boolean
}>()
function getEditorConfig(): EditorConfig {
let editorConfig: EditorConfig = {
tools: {
Header,
Quote,
NestedList,
Code,
Table,
Warning,
Delimiter,
Marker,
Underline
},
i18n
}
if (!props.showDefaultData) return editorConfig
editorConfig = {
...editorConfig,
data: defaultData
}
return editorConfig
}
const editor = new EditorJS(getEditorConfig())
async function getEditorData(): Promise<OutputData | undefined> {
let data = undefined
await editor.save()
.then(outputData => {
data = outputData
})
.catch((error) => {
console.error(error)
})
return data
}
</script>
<template>
<div class="container">
<div id="editorjs"></div>
<button @click="getEditorData()" class="button-primary">Enregistrer</button>
</div>
</template>
<style scoped>
.container {
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
}
#editorjs {
font-family: 'Hind', sans-serif;
}
button {
margin: auto;
}
</style>
+41 -50
View File
@@ -1,71 +1,62 @@
<script setup lang="ts">
// import EditorJS from '@editorjs/editorjs';
import { useAuthStore, type jwtFormat } from '@/stores/AuthStore';
import Editor from '@/components/Editor.vue';
import { useAuthStore } from '@/stores/AuthStore';
import { ref } from 'vue';
const email = ref('')
const password = ref('')
const baseURL = `http://${__APP_ENV__.APP_HOST_ADDRESS}:${__APP_ENV__.APP_API_PORT}`
const articleID = ref('')
function getArticles() {
fetch(`${baseURL}/articles/`, {
function getArticles(id?: string) {
fetch(`${baseURL}/articles/${id ?? ''}`, {
headers: { "Authorization": `Bearer ${useAuthStore().token}` }
})
.then(response => response.json())
.then(result => console.log(result))
.then(response => response.json())
.then(result => console.log(result))
}
function ping() {
fetch(`${baseURL}/ping/`, {
headers: { "Authorization": `Bearer ${useAuthStore().token}` }
})
.then(response => response.json())
.then(result => console.log(result))
}
function jwtHandler(apiResponse: jwtFormat): void {
if (apiResponse.code !== 200) {
console.log(apiResponse)
return
}
useAuthStore().token = apiResponse.token
useAuthStore().expire = apiResponse.expire
console.log('success! logged in.')
}
function login(email: string, password: string): void {
fetch(`${baseURL}/login/`, {
method: "POST",
body: JSON.stringify({
email: email,
password: password
})
})
.then(response => response.json())
.then(result => jwtHandler(result))
.then(response => response.json())
.then(result => console.log(result))
}
</script>
<template>
<h2>Connexion</h2>
<form @submit.prevent="login(email, password)">
<div class="inputs-group">
<div>
<label for="email">Email address</label>
<input id="email" name="email" placeholder="email" type="text" v-model="email">
</div>
<div>
<label for="password">Password</label>
<input id="password" name="password" placeholder="password" type="password" v-model="password">
</div>
<button type="submit">Se connecter</button>
</form>
<div>
<div>
<button class="button-primary" @click="getArticles()">get all articles</button>
<button class="button-primary" @click="ping()">ping</button>
<input type="text" placeholder="article ID" v-model="articleID">
<button class="button-primary" @click="getArticles(articleID)">get article</button>
</div>
</div>
<div class="buttons-group">
<button class="button-primary" @click="ping()">ping</button>
</div>
<div class="editor">
<Editor :show-default-data="true"></Editor>
</div>
</template>
<style scoped>
.buttons-group,
.inputs-group {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin: 32px;
}
.inputs-group {
flex-direction: column;
}
.inputs-group div {
flex-direction: row;
gap: 8px;
}
.editor {
border: solid black 2px;
}
</style>