simplifying article publishing process
This commit is contained in:
parent
f958d0b119
commit
dff43012a5
238
components.js
238
components.js
@ -2505,7 +2505,18 @@ customElements.define('sm-select', class extends HTMLElement {
|
||||
return this.getAttribute('value')
|
||||
}
|
||||
set value(val) {
|
||||
this.setAttribute('value', val)
|
||||
const selectedOption = this.availableOptions.find(option => option.getAttribute('value') === val)
|
||||
if (selectedOption) {
|
||||
this.setAttribute('value', val)
|
||||
this.selectedOptionText.textContent = `${this.label}${selectedOption.textContent}`;
|
||||
if (this.previousOption) {
|
||||
this.previousOption.classList.remove('check-selected')
|
||||
}
|
||||
selectedOption.classList.add('check-selected')
|
||||
this.previousOption = selectedOption
|
||||
} else {
|
||||
console.warn(`There is no option with ${val} as value`)
|
||||
}
|
||||
}
|
||||
|
||||
reset(fire = true) {
|
||||
@ -2581,13 +2592,7 @@ customElements.define('sm-select', class extends HTMLElement {
|
||||
handleOptionSelection(e) {
|
||||
if (this.previousOption !== document.activeElement) {
|
||||
this.value = document.activeElement.getAttribute('value')
|
||||
this.selectedOptionText.textContent = `${this.label}${document.activeElement.textContent}`;
|
||||
this.fireEvent()
|
||||
if (this.previousOption) {
|
||||
this.previousOption.classList.remove('check-selected')
|
||||
}
|
||||
document.activeElement.classList.add('check-selected')
|
||||
this.previousOption = document.activeElement
|
||||
}
|
||||
}
|
||||
handleClick(e) {
|
||||
@ -4290,222 +4295,3 @@ customElements.define('sm-textarea',
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const tagsInput = document.createElement('template')
|
||||
tagsInput.innerHTML = `
|
||||
<style>
|
||||
*{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
:host{
|
||||
--accent-color: #4d2588;
|
||||
--text-color: 17, 17, 17;
|
||||
--background-color: 255, 255, 255;
|
||||
--danger-color: red;
|
||||
--border-radius: 0.3rem;
|
||||
--background: rgba(var(--text-color), 0.06);
|
||||
}
|
||||
.hide{
|
||||
display: none !important;
|
||||
}
|
||||
.tags-wrapper{
|
||||
position: relative;
|
||||
display: flex;
|
||||
cursor: text;
|
||||
flex-wrap: wrap;
|
||||
justify-items: flex-start;
|
||||
align-items: center;
|
||||
padding: 0.5rem 0.5rem 0 0.5rem;
|
||||
border-radius: var(--border-radius);
|
||||
background: var(--background);
|
||||
}
|
||||
.tags-wrapper:focus-within{
|
||||
box-shadow: 0 0 0 0.1rem var(--accent-color) inset !important;
|
||||
}
|
||||
|
||||
.tag {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
border-radius: 0.3rem;
|
||||
padding: 0.3rem 0.5rem;
|
||||
margin: 0 0.5rem 0.5rem 0;
|
||||
background-color: rgba(var(--text-color), 0.06);
|
||||
}
|
||||
|
||||
.icon {
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
margin-left: 0.3rem;
|
||||
fill: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
|
||||
input,
|
||||
input:focus {
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
input {
|
||||
display: inline-flex;
|
||||
width: auto;
|
||||
color: inherit;
|
||||
max-width: inherit;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
padding: 0.4rem 0.5rem;
|
||||
margin: 0 0.5rem 0.5rem 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
.placeholder{
|
||||
position: absolute;
|
||||
padding: 0 0.5rem;
|
||||
top: 50%;
|
||||
font-weight: 500;
|
||||
transform: translateY(-50%);
|
||||
color: rgba(var(--text-color), 0.6);
|
||||
}
|
||||
</style>
|
||||
<div class="tags-wrapper">
|
||||
<input type="text" size="3"/>
|
||||
<p class="placeholder"></p>
|
||||
</div>
|
||||
`
|
||||
|
||||
customElements.define('tags-input', class extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.attachShadow({
|
||||
mode: 'open'
|
||||
}).append(tagsInput.content.cloneNode(true))
|
||||
|
||||
this.input = this.shadowRoot.querySelector('input')
|
||||
this.tagsWrapper = this.shadowRoot.querySelector('.tags-wrapper')
|
||||
this.placeholder = this.shadowRoot.querySelector('.placeholder')
|
||||
this.reflectedAttributes = ['placeholder', 'limit']
|
||||
this.limit = undefined
|
||||
this.tags = new Set()
|
||||
|
||||
this.reset = this.reset.bind(this)
|
||||
this.handleInput = this.handleInput.bind(this)
|
||||
this.handleKeydown = this.handleKeydown.bind(this)
|
||||
this.handleClick = this.handleClick.bind(this)
|
||||
this.removeTag = this.removeTag.bind(this)
|
||||
}
|
||||
static get observedAttributes() {
|
||||
return ['placeholder', 'limit']
|
||||
}
|
||||
get value() {
|
||||
return [...this.tags]
|
||||
}
|
||||
get isValid() {
|
||||
return this.tags.size
|
||||
}
|
||||
focusIn() {
|
||||
this.input.focus()
|
||||
}
|
||||
reset() {
|
||||
this.input.value = ''
|
||||
this.tags.clear()
|
||||
while (this.input.previousElementSibling) {
|
||||
this.input.previousElementSibling.remove()
|
||||
}
|
||||
}
|
||||
handleInput(e) {
|
||||
const inputValueLength = e.target.value.trim().length
|
||||
e.target.setAttribute('size', inputValueLength ? inputValueLength : '3')
|
||||
if (inputValueLength) {
|
||||
this.placeholder.classList.add('hide')
|
||||
}
|
||||
else if (!inputValueLength && !this.tags.size) {
|
||||
this.placeholder.classList.remove('hide')
|
||||
}
|
||||
}
|
||||
handleKeydown(e) {
|
||||
if (e.key === ',' || e.key === '/') {
|
||||
e.preventDefault()
|
||||
}
|
||||
if (e.target.value.trim() !== '') {
|
||||
if (e.key === 'Enter' || e.key === ',' || e.key === '/') {
|
||||
const tagValue = e.target.value.trim()
|
||||
if (this.tags.has(tagValue)) {
|
||||
this.tagsWrapper.querySelector(`[data-value="${tagValue}"]`).animate([
|
||||
{
|
||||
backgroundColor: 'initial'
|
||||
},
|
||||
{
|
||||
backgroundColor: 'var(--accent-color)'
|
||||
},
|
||||
{
|
||||
backgroundColor: 'initial'
|
||||
},
|
||||
], {
|
||||
duration: 300,
|
||||
easing: 'ease'
|
||||
})
|
||||
}
|
||||
else {
|
||||
const tag = document.createElement('span')
|
||||
tag.dataset.value = tagValue
|
||||
tag.className = 'tag'
|
||||
tag.innerHTML = `
|
||||
<span class="tag-text">${tagValue}</span>
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>
|
||||
`
|
||||
this.input.before(tag)
|
||||
this.tags.add(tagValue)
|
||||
}
|
||||
e.target.value = ''
|
||||
e.target.setAttribute('size', '3')
|
||||
if (this.limit && this.limit < this.tags.size + 1) {
|
||||
this.input.readOnly = true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (e.key === 'Backspace' && this.input.previousElementSibling) {
|
||||
this.removeTag(this.input.previousElementSibling)
|
||||
}
|
||||
if (this.limit && this.limit > this.tags.size) {
|
||||
this.input.readOnly = false
|
||||
}
|
||||
}
|
||||
}
|
||||
handleClick(e) {
|
||||
if (e.target.closest('.tag')) {
|
||||
this.removeTag(e.target.closest('.tag'))
|
||||
}
|
||||
else {
|
||||
this.input.focus()
|
||||
}
|
||||
}
|
||||
removeTag(tag) {
|
||||
this.tags.delete(tag.dataset.value)
|
||||
tag.remove()
|
||||
if (!this.tags.size) {
|
||||
this.placeholder.classList.remove('hide')
|
||||
}
|
||||
}
|
||||
connectedCallback() {
|
||||
this.input.addEventListener('input', this.handleInput)
|
||||
this.input.addEventListener('keydown', this.handleKeydown)
|
||||
this.tagsWrapper.addEventListener('click', this.handleClick)
|
||||
}
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (name === 'placeholder') {
|
||||
this.placeholder.textContent = newValue
|
||||
}
|
||||
if (name === 'limit') {
|
||||
this.limit = parseInt(newValue)
|
||||
}
|
||||
}
|
||||
disconnectedCallback() {
|
||||
this.input.removeEventListener('input', this.handleInput)
|
||||
this.input.removeEventListener('keydown', this.handleKeydown)
|
||||
this.tagsWrapper.removeEventListener('click', this.handleClick)
|
||||
}
|
||||
})
|
||||
41
index.html
41
index.html
@ -537,38 +537,6 @@
|
||||
<span class="label">Copy link</span>
|
||||
<sm-copy id="shared_url" clip-text></sm-copy>
|
||||
</sm-popup>
|
||||
<sm-popup id="publish_article_popup">
|
||||
<header slot="header" class="popup__header">
|
||||
<div class="flex align-center">
|
||||
<button class="popup__header__close" onclick="hidePopup()">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
|
||||
fill="#000000">
|
||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||
<path
|
||||
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
|
||||
</svg>
|
||||
</button>
|
||||
<h3>Publish article</h3>
|
||||
</div>
|
||||
</header>
|
||||
<sm-form class="grid gap-1-5">
|
||||
<div class="grid gap-0-5">
|
||||
<h5>Select category</h5>
|
||||
<sm-select id="published_article_category">
|
||||
<sm-option value="entertainment">Entertainment</sm-option>
|
||||
<sm-option value="politics">Politics</sm-option>
|
||||
<sm-option value="science">Science</sm-option>
|
||||
<sm-option value="sports">Sports</sm-option>
|
||||
<sm-option value="tech">Tech</sm-option>
|
||||
</sm-select>
|
||||
</div>
|
||||
<div class="grid gap-0-5">
|
||||
<h5>Add tags</h5>
|
||||
<tags-input id="article_tags" limit="10"></tags-input>
|
||||
</div>
|
||||
<sm-button variant="primary" onclick="publishArticle()">Request publishing</sm-button>
|
||||
</sm-form>
|
||||
</sm-popup>
|
||||
<sm-popup id="user_popup">
|
||||
<header slot="header" class="popup__header">
|
||||
<div class="flex align-center">
|
||||
@ -1692,8 +1660,6 @@
|
||||
|
||||
function publishArticle() {
|
||||
if (floGlobals.isSubAdmin) {
|
||||
const category = getRef('published_article_category').value
|
||||
const tags = getRef('article_tags').value
|
||||
getConfirmation('Request publishing?', {
|
||||
message: 'Send this article as publishing candidate on RanchiMall TImes',
|
||||
confirmText: 'Request'
|
||||
@ -1711,10 +1677,7 @@
|
||||
title: floGlobals.appObjects.cc.articleList[floGlobals.currentArticle.id].title,
|
||||
content,
|
||||
readTime,
|
||||
category,
|
||||
tags,
|
||||
contributors: [...allContributors]
|
||||
|
||||
contributors: [...allContributors],
|
||||
}, 'publishing_requests', {
|
||||
application: 'Test_RM_Times',
|
||||
receiverID: 'FKAEdnPfjXLHSYwrXQu377ugN4tXU7VGdf'
|
||||
@ -2600,7 +2563,7 @@
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <g> <rect fill="none" height="24" width="24" /> </g> <g> <path d="M18,15v3H6v-3H4v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3H18z M17,11l-1.41-1.41L13,12.17V4h-2v8.17L8.41,9.59L7,11l5,5 L17,11z" /> </g> </svg>
|
||||
</button>
|
||||
`: ''}
|
||||
<sm-button variant="primary" onclick="${floGlobals.isSubAdmin ? "showPopup('publish_article_popup')" : 'exportSelection()'}">
|
||||
<sm-button variant="primary" onclick="${floGlobals.isSubAdmin ? "showPopup('publishArticle')" : 'exportSelection()'}">
|
||||
${floGlobals.isSubAdmin ? `
|
||||
<svg class="icon button__icon--left" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <path d="M0 0h24v24H0V0z" fill="none" /> <path d="M5 4h14v2H5zm0 10h4v6h6v-6h4l-7-7-7 7zm8-2v6h-2v-6H9.83L12 9.83 14.17 12H13z" /> </svg>
|
||||
Publish
|
||||
|
||||
Loading…
Reference in New Issue
Block a user