Start working on details panel

This commit is contained in:
Robbie Antenesse 2019-05-02 15:45:10 -06:00
parent c4b7fa4257
commit 5311aeea9d
8 changed files with 237 additions and 5 deletions

View File

@ -39,10 +39,10 @@
<h2>Dictionary Name</h2>
<nav>
<ul>
<li id="toggleDescription">Description</li><li id="toggleDetails">Details</li><li id="toggleStats" class="active">Stats</li><li id="showEdit" onclick="document.getElementById('editModal').style.display='block'">Edit</li>
<li>Description</li><li>Details</li><li>Stats</li><li onclick="document.getElementById('editModal').style.display='block'">Edit</li>
</ul>
</nav>
<article id="detailsPanel">
<article id="detailsPanel" style="display:none;">
<p>The dictionary details</p>
</article>
</section>

View File

@ -14,6 +14,7 @@
"sass": "^1.19.0"
},
"dependencies": {
"normalize.css": "^8.0.1"
"normalize.css": "^8.0.1",
"snarkdown": "^1.2.2"
}
}

51
src/constants.js Normal file
View File

@ -0,0 +1,51 @@
export const DEFAULT_DICTIONARY = {
name: 'New',
specification: 'Dictionary',
description: 'A new dictionary.',
partsOfSpeech: ['Noun', 'Adjective', 'Verb'],
alphabeticalOrder: [],
details: {
phonology: {
consonants: [],
vowels: [],
blends: [],
phonotactics: {
onset: [],
nucleus: [],
coda: [],
exceptions: '',
},
},
orthography: {
notes: '',
},
grammar: {
notes: '',
},
// custom: [
// // {
// // name: 'Example Tab',
// // content: `This is an _example_ tab to show how **tabs** work with [Markdown](${ MARKDOWN_LINK })!`,
// // }
// ],
},
words: [
/* {
name: '',
pronunciation: '',
partOfSpeech: '',
simpleDefinition: '',
longDefinition: '',
wordId: 0
}, */
],
settings: {
allowDuplicates: false,
caseSensitive: false,
sortByDefinition: false,
isComplete: false,
isPublic: false,
},
lastUpdated: null,
createdOn: 0,
};

View File

@ -1,7 +1,12 @@
import './main.scss';
import { DEFAULT_DICTIONARY } from './constants';
import setupListeners from './js/setupListeners';
function initialize() {
console.log('initializing');
window.currentDictionary = JSON.parse(JSON.stringify(DEFAULT_DICTIONARY));
setupListeners();
}
window.onload = (function (oldLoad) {

131
src/js/displayToggles.js Normal file
View File

@ -0,0 +1,131 @@
import md from 'snarkdown';
export function showSection(sectionName) {
switch (sectionName) {
case 'description': showDescription(); break;
case 'details': showDetails(); break;
case 'stats': showStats(); break;
}
}
function showDescription() {
const detailsPanel = document.getElementById('detailsPanel');
detailsPanel.style.display = 'block';
const {description} = window.currentDictionary;
const descriptionHTML = md(description);
detailsPanel.innerHTML = descriptionHTML;
}
function showDetails() {
const detailsPanel = document.getElementById('detailsPanel');
detailsPanel.style.display = 'block';
const {partsOfSpeech, alphabeticalOrder} = window.currentDictionary;
const {phonology, orthography, grammar} = window.currentDictionary.details;
const partsOfSpeechHTML = `<p><strong>Parts of Speech:</strong> ${partsOfSpeech.map(partOfSpeech => '<span class="tag">' + partOfSpeech + '</span>').join(' ')}</p>`;
const alphabeticalOrderHTML = `<p><strong>Alphabetical Order:</strong> ${
(alphabeticalOrder.length > 0 ? alphabeticalOrder : ['English Alphabet']).map(letter => `<span class="tag">${letter}</span>`).join(' ')
}</p>`;
detailsPanel.innerHTML = partsOfSpeechHTML + alphabeticalOrderHTML;
}
function showStats() {
const detailsPanel = document.getElementById('detailsPanel');
detailsPanel.style.display = 'block';
const wordStats = getWordsStats();
const numberOfWordsHTML = `<p><strong>Number of Words</strong><br>${wordStats.numberOfWords.map(stat => `<span><span class="tag">${stat.name}</span><span class="tag">${stat.value}</span></span>`).join(' ')}</p>`;
detailsPanel.innerHTML = numberOfWordsHTML;
}
function getWordsStats() {
const {words, partsOfSpeech} = window.currentDictionary;
const {caseSensitive} = window.currentDictionary.settings;
const wordStats = {
numberOfWords: [
{
name: 'Total',
value: words.length,
},
],
wordLength: {
shortest: 0,
longest: 0,
average: 0,
},
letterDistribution: [
/* {
letter: '',
number: 0,
percentage: 0.00,
} */
],
totalLetters: 0,
};
partsOfSpeech.forEach(partOfSpeech => {
const wordsWithPartOfSpeech = words.filter(word => word.partOfSpeech === partOfSpeech);
wordStats.numberOfWords.push({
name: partOfSpeech,
value: wordsWithPartOfSpeech.length,
});
});
wordStats.numberOfWords.push({
name: 'Unclassified',
value: words.filter(word => !partsOfSpeech.includes(word.partOfSpeech)).length,
});
let totalLetters = 0;
const numberOfLetters = {};
words.forEach(word => {
const shortestWord = wordStats.wordLength.shortest;
const longestWord = wordStats.wordLength.longest;
const wordLetters = word.name.split('');
const lettersInWord = wordLetters.length;
totalLetters += lettersInWord;
if (shortestWord === 0 || lettersInWord < shortestWord) {
wordStats.wordLength.shortest = lettersInWord;
}
if (longestWord === 0 || lettersInWord > longestWord) {
wordStats.wordLength.longest = lettersInWord;
}
wordLetters.forEach(letter => {
const letterToUse = caseSensitive ? letter : letter.toLowerCase();
if (!numberOfLetters.hasOwnProperty(letterToUse)) {
numberOfLetters[letterToUse] = 1;
} else {
numberOfLetters[letterToUse]++;
}
});
});
wordStats.totalLetters = totalLetters;
wordStats.wordLength.average = totalLetters / words.length;
for (const letter in numberOfLetters) {
if (numberOfLetters.hasOwnProperty(letter)) {
const number = numberOfLetters[letter];
wordStats.letterDistribution.push({
letter,
number,
percentage: number / totalLetters,
});
}
}
wordStats.letterDistribution.sort((a, b) => {
if (a.percentage === b.percentage) return 0;
return (a.percentage > b.percentage) ? -1 : 1;
});
return wordStats;
}

22
src/js/setupListeners.js Normal file
View File

@ -0,0 +1,22 @@
import {showSection} from './displayToggles';
export default function setupListeners() {
setupDetailsTabs();
}
function setupDetailsTabs () {
let tabs = document.querySelectorAll('#detailsSection nav li');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const section = tab.innerText.toLowerCase();
const isActive = tab.classList.contains('active');
tabs.forEach(t => t.classList.remove('active'));
if (isActive) {
document.getElementById('detailsPanel').style.display = 'none';
} else {
tab.classList.add('active');
showSection(section);
}
});
})
}

View File

@ -1,9 +1,26 @@
.button {
cursor: pointer;
.tag {
padding: 3px 9px;
border: $border;
border-radius: 3px;
background-color: $light;
line-height: 30px;
}
span .tag {
@extend .tag;
border-radius: 3px 0 0 3px;
&+.tag {
border-left: none;
border-radius: 0 3px 3px 0;
background-color: $white;
}
}
.button {
@extend .tag;
cursor: pointer;
}
.modal {

View File

@ -4542,6 +4542,11 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
snarkdown@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/snarkdown/-/snarkdown-1.2.2.tgz#0cfe2f3012b804de120fc0c9f7791e869c59cc74"
integrity sha1-DP4vMBK4BN4SD8DJ93kehpxZzHQ=
source-map-resolve@^0.5.0:
version "0.5.2"
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259"