Commit cd70b934 by Рамис

add attach files

add unset highlighter and text color
parent 85d05f2c
......@@ -7,7 +7,9 @@ import 'react-ag-qeditor/dist/index.css'
const App = () => {
return <div style={{padding:40}}>
<QEditor
value={'<iframe src="https://www.youtube.com/embed/I7vc0lESM6c" frameborder="0" allowfullscreen="true"></iframe><p>asfdnasjkfasf</p>'}
value={'<p>Магма покрывает биотит. Деградация мерзлоты изменяет меандр, в тоже время поднимаясь в пределах горстов до абсолютных высот 250 м. Количество пирокластического материала в связи с преобладанием карьерной разработки ископаемых прекращает фирновый гетит. Синеклиза косвенно пододвигается под кряж, что лишь подтверждает то, что породные отвалы располагаются на склонах.</p>\n' +
'<p>Можно ожидать, что мергель опускает флювиогляциальный ортоклаз. Колонны могут образоваться после того, как брекчия длительно прекращает флювиогляциальный батолит. Габбро слагает оз, делая этот типологический таксон районирования носителем важнейших инженерно-геологических характеристик природных условий. Кайнозой обеднен. Извержение спорадически ослабляет днепровский рифт. Оттаивание пород, из которого на 50% состоит руда месторождения, неоднозначно переоткладывает железистый биотит.</p>\n' +
'<p>Зандровое поле, особенно в верхах разреза, постоянно разогревает кристаллический грунт, что в конце концов приведет к полному разрушению хребта под действием собственного веса. Большое значение для формирования химического состава грунтовых и пластовых вод имеет выклинивание стягивает гидротермальный базальтовый слой. Сель, используя геологические данные нового типа, сдвигает днепровский блеск.</p>'}
onChange={(value)=>{
console.log('sads', value);
}}
......@@ -22,5 +24,4 @@ const App = () => {
/>
</div>
}
export default App
......@@ -36,7 +36,6 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
const [modalIsOpen, setModalIsOpen] = useState(false);
const [modalTitle, setModalTitle] = useState('');
const [bubbleItems, setBubbleItems] = useState(initialBubbleItems);
const [colorsTabsActive, setColorsTabsActive] = useState('color'); //highlight || color
const [colorsSelected, setColorsSelected] = useState(null);
const [focusFromTo, setFocusFromTo] = useState(null);
const [oldFocusFromTo, setOldFocusFromTo] = useState(null);
......@@ -57,20 +56,38 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
setInnerModalType(type);
setModalIsOpen(true);
}
const colors = [
'#9B9B9B',
'#CCCCCC',
'#9ee191',
'#43e7bf',
'#4fb7ff',
'#6d9ef5',
'#cd92e8',
'#f597bc',
'#fa9084',
'#ef9558',
'#dea75b',
'#ffe672'
];
const colors = {
color: [
'none',
'#8a8a8a',
'#afafaf',
'#44d724',
'#0bd9b2',
'#4fb7ff',
'#226aff',
'#b153e5',
'#f54f8e',
'#f34c37',
'#ee7027',
'#d27303',
'#ffd102'
],
highlight: [
'none',
'#9B9B9B',
'#CCCCCC',
'#9ee191',
'#43e7bf',
'#4fb7ff',
'#6d9ef5',
'#cd92e8',
'#f597bc',
'#fa9084',
'#ef9558',
'#dea75b',
'#ffe672'
]
};
const toolsLib = {
link: {
......@@ -249,7 +266,6 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
editor.chain().focus();
}
},
highlight: {
title: 'Цвет фона',
onClick: () => setColorsSelected('highlight')
......@@ -329,11 +345,21 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
)
}
const getUploader = ({ accept = '*' }) => {
const getUploader = ({ accept = '*', ...o }) => {
let url = uploadOptions.url;
if(o.afterParams && o.afterParams.length > 0){
if(uploadOptions.url.indexOf('?') !== -1){
url = uploadOptions.url + '&' + o.afterParams.join('&');
}else{
url = uploadOptions.url + '?' + o.afterParams.join('&');
}
}
return <Uploader
key={uploaderUid}
accept={ accept }
action={ uploadOptions.url }
action={ url }
errorMessage={ uploadOptions.errorMessage }
onSuccess={(file) => {
let _uploadedPaths = [...uploadedPaths];
......@@ -354,6 +380,7 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
setUploadedPaths(_uploadedPaths)
}}
multiple={true}
modalType={ innerModalType }
/>
}
......@@ -375,7 +402,7 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
)
case 'video':
return (
<Fragment>{ getUploader({ accept: 'video/*' }) }</Fragment>
<Fragment>{ getUploader({ accept: 'video/x-msvideo, video/quicktime, video/x-matroska, video/mp4, video/x-ms-wmv' }) }</Fragment>
)
case 'image':
return (
......@@ -383,7 +410,7 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
)
case 'file':
return (
<Fragment>{ getUploader({ accept: '*' }) }</Fragment>
<Fragment>{ getUploader({ accept: '*', afterParams: ['no_convert=1'] }) }</Fragment>
)
default:
return <div>Пусто</div>
......@@ -461,11 +488,19 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
<div className={"atma-editor-bubble"} onClick={e => e.stopPropagation()}>
{
colorsSelected !== null ?
colors.map((itemColor, i) => {
return ( <div key={'colors' + i} className={'qcolors'} style={{ background: itemColor}} onClick={()=>{
colorsSelected === 'color' ?
editor.chain().focus().unsetHighlight().setColor(itemColor).run() :
editor.chain().focus().unsetColor().toggleHighlight({ color: itemColor }).run()
colors[colorsSelected].map((itemColor, i) => {
return ( <div key={'colors' + colorsSelected + i} className={'qcolors' + (itemColor === 'none' ? ' unset' : '')} style={{ background: itemColor}} onClick={()=>{
if(itemColor === 'none'){
colorsSelected === 'color' ?
editor.chain().focus().unsetHighlight().unsetColor().run() :
editor.chain().focus().unsetColor().unsetHighlight().run();
}else{
colorsSelected === 'color' ?
editor.chain().focus().unsetHighlight().setColor(itemColor).run() :
editor.chain().focus().unsetColor().toggleHighlight({ color: itemColor }).run();
}
setColorsSelected(null);
}} /> )
}) : bubbleItems.map((type, i) => {
......@@ -564,19 +599,23 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
break
case 'file':
console.log(uploadedPaths, 'ejkwnferiugnuierwnguirne');
uploadedPaths.map((file, i) => {
console.log(file);
editor
.chain().focus()
.extendMarkRange('link').setLink({
href: file.path,
target: '_blank',
download: true,
'data-size': '100 кб'
})
.insertContent('Example Text')
// .extendMarkRange('link').setLink({
// href: file.path,
// target: '_blank',
// download: true,
// 'data-size': file.size
// })
.insertContent(`<a href="${file.path}" target="_blank" download="true" data-size="${file.size}">${file.name}</a>`)
.run();
});
break
}
......
......@@ -46,7 +46,7 @@ const ToolBar = ({ editor, toolsLib = [] }) => {
type: 'g',
items: [
'link',
// 'file',
'file',
'image',
'video',
'iframe',
......@@ -95,6 +95,29 @@ const ToolBar = ({ editor, toolsLib = [] }) => {
return editor.isActive(type);
}
const isDisabled = (type) => {
// console.log(type);
switch (type){
case 'addRowBefore':
case 'addRowAfter':
case 'deleteRow':
case 'addColumnBefore':
case 'addColumnAfter':
case 'deleteColumn':
case 'toggleHeaderCell':
case 'mergeOrSplit':
case 'deleteTable':
if(!editor.isActive('table')){
return true;
}
}
return false
}
const getItem = (type = null, idx, isTitle = false) => {
let item = null;
......@@ -116,7 +139,7 @@ const ToolBar = ({ editor, toolsLib = [] }) => {
e.stopPropagation()
return false;
}}
className={`atma-editor-toolbar-s-opts-item` + (isActive(type) ? ' active' : '')}
className={`atma-editor-toolbar-s-opts-item` + (isActive(type) ? ' active' : '' ) + (isDisabled(type) ? ' disabled' : '')}
>
<Fragment>
<div className={`qicon q${type}`} />
......
......@@ -35,9 +35,9 @@ export default class Uploader extends React.Component {
this.files = {};
}
componentDidUpdate (prevProps, prevState, snapshot) {
console.log(this.state.files);
}
// componentDidUpdate (prevProps, prevState, snapshot) {
// console.log(this.state.files);
// }
get action () {
return this.props.action;
......@@ -67,6 +67,10 @@ export default class Uploader extends React.Component {
return this.props.errorMessage;
}
get modalType () {
return this.props.modalType;
}
mediaItem(){
}
......@@ -109,8 +113,9 @@ export default class Uploader extends React.Component {
{
Object.keys(this.state.files).map((uid, i) => (
<div
className={ 'atma-editor-uploader-uitems-elem' }
className={ 'atma-editor-uploader-uitems-elem' + (this.modalType === 'file' ? ' atma-editor-uploader-file' : '' ) }
style={{ backgroundImage: `url(${this.state.files[uid].path})` }}
data-url={ this.state.files[uid].path }
>
<div className={'atma-editor-uploader-uitems-del'} title={'Удалить'} onClick={()=> this.abortUpload({ uid }) } />
{
......@@ -122,6 +127,7 @@ export default class Uploader extends React.Component {
</div>
) : null
}
{ this.modalType === 'file' && <span>{ this.state.files[uid].name }</span> }
</div>
))
}
......@@ -150,11 +156,20 @@ export default class Uploader extends React.Component {
curFile['uploaded'] = true;
curFile['path'] = resp.poster || resp.file_path;
curFile['name'] = resp.file_name;
curFile['size'] = resp.file_size;
this.setState({
uploaderSuccess: true,
isUpload: false,
disabledFileUpload: false
}, () => this.onSuccess({path: resp.file_path, uid: file.uid}))
disabledFileUpload: false,
files: this.files
}, () => this.onSuccess({
path: resp.file_path,
uid: file.uid,
name: resp.file_name,
size: resp.file_size
}))
}
}}
......@@ -188,4 +203,5 @@ Uploader.defaultProps = {
type: '',
onSuccess: ()=>{},
errorMessage: null,
modalType: null
};
......@@ -359,6 +359,20 @@ body{
background-size: cover;
background-position: center;
aspect-ratio: 16 / 9;
&.atma-editor-uploader-file{
background-image: url('data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%2213%22%20height%3D%2216%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M3.712%2012.6H8.86c.17%200%20.31-.057.422-.17a.588.588%200%200%200%20.167-.43.588.588%200%200%200-.167-.43.567.567%200%200%200-.422-.17H3.713a.567.567%200%200%200-.423.17.588.588%200%200%200-.167.43c0%20.173.056.317.167.43.111.113.252.17.422.17zm0-3.4H8.86c.17%200%20.31-.057.422-.17a.588.588%200%200%200%20.167-.43.588.588%200%200%200-.167-.43A.567.567%200%200%200%208.86%208H3.713a.567.567%200%200%200-.423.17.588.588%200%200%200-.167.43c0%20.173.056.317.167.43.111.113.252.17.422.17zM1.18%2016c-.315%200-.59-.12-.825-.36A1.161%201.161%200%200%201%200%2014.8V1.2C0%20.88.118.6.354.36.589.12.864%200%201.179%200h6.6a1.164%201.164%200%200%201%20.844.36l3.595%203.66a1.214%201.214%200%200%201%20.353.86v9.92c0%20.32-.117.6-.353.84s-.51.36-.825.36H1.179zM7.68%201.2H1.18v13.6h10.214V4.92H8.27a.567.567%200%200%201-.423-.17.588.588%200%200%201-.167-.43V1.2zm-6.501%200v3.72V1.2%2014.8%201.2z%22%20fill%3D%22%231790FF%22%20fill-rule%3D%22nonzero%22%2F%3E%3C%2Fsvg%3E') !important;
background-position: center top;
background-size: 30px;
aspect-ratio: auto;
width: 76px;
min-height: 56px;
background-color: transparent;
padding-top: 40px;
font-size: 11px;
margin-right: 30px;
vertical-align: top;
}
}
&-del{
......@@ -381,6 +395,8 @@ body{
}
}
}
&-progress{
......@@ -691,6 +707,23 @@ body{
&:hover{
cursor: pointer;
}
&.unset{
position: relative;
box-shadow: inset 0 0 1px 0 black;
overflow: hidden;
&:before{
content: '';
background-color: tomato;
width: 120%;
height: 2px;
transform: rotate(-45deg);
position: absolute;
top: calc(50% - 1px);
left: -1px;
}
}
}
.qseparator{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment