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' ...@@ -7,7 +7,9 @@ import 'react-ag-qeditor/dist/index.css'
const App = () => { const App = () => {
return <div style={{padding:40}}> return <div style={{padding:40}}>
<QEditor <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)=>{ onChange={(value)=>{
console.log('sads', value); console.log('sads', value);
}} }}
...@@ -22,5 +24,4 @@ const App = () => { ...@@ -22,5 +24,4 @@ const App = () => {
/> />
</div> </div>
} }
export default App export default App
...@@ -36,7 +36,6 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => { ...@@ -36,7 +36,6 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
const [modalIsOpen, setModalIsOpen] = useState(false); const [modalIsOpen, setModalIsOpen] = useState(false);
const [modalTitle, setModalTitle] = useState(''); const [modalTitle, setModalTitle] = useState('');
const [bubbleItems, setBubbleItems] = useState(initialBubbleItems); const [bubbleItems, setBubbleItems] = useState(initialBubbleItems);
const [colorsTabsActive, setColorsTabsActive] = useState('color'); //highlight || color
const [colorsSelected, setColorsSelected] = useState(null); const [colorsSelected, setColorsSelected] = useState(null);
const [focusFromTo, setFocusFromTo] = useState(null); const [focusFromTo, setFocusFromTo] = useState(null);
const [oldFocusFromTo, setOldFocusFromTo] = useState(null); const [oldFocusFromTo, setOldFocusFromTo] = useState(null);
...@@ -57,7 +56,24 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => { ...@@ -57,7 +56,24 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
setInnerModalType(type); setInnerModalType(type);
setModalIsOpen(true); setModalIsOpen(true);
} }
const colors = [ const colors = {
color: [
'none',
'#8a8a8a',
'#afafaf',
'#44d724',
'#0bd9b2',
'#4fb7ff',
'#226aff',
'#b153e5',
'#f54f8e',
'#f34c37',
'#ee7027',
'#d27303',
'#ffd102'
],
highlight: [
'none',
'#9B9B9B', '#9B9B9B',
'#CCCCCC', '#CCCCCC',
'#9ee191', '#9ee191',
...@@ -70,7 +86,8 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => { ...@@ -70,7 +86,8 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
'#ef9558', '#ef9558',
'#dea75b', '#dea75b',
'#ffe672' '#ffe672'
]; ]
};
const toolsLib = { const toolsLib = {
link: { link: {
...@@ -249,7 +266,6 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => { ...@@ -249,7 +266,6 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
editor.chain().focus(); editor.chain().focus();
} }
}, },
highlight: { highlight: {
title: 'Цвет фона', title: 'Цвет фона',
onClick: () => setColorsSelected('highlight') onClick: () => setColorsSelected('highlight')
...@@ -329,11 +345,21 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => { ...@@ -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 return <Uploader
key={uploaderUid} key={uploaderUid}
accept={ accept } accept={ accept }
action={ uploadOptions.url } action={ url }
errorMessage={ uploadOptions.errorMessage } errorMessage={ uploadOptions.errorMessage }
onSuccess={(file) => { onSuccess={(file) => {
let _uploadedPaths = [...uploadedPaths]; let _uploadedPaths = [...uploadedPaths];
...@@ -354,6 +380,7 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => { ...@@ -354,6 +380,7 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
setUploadedPaths(_uploadedPaths) setUploadedPaths(_uploadedPaths)
}} }}
multiple={true} multiple={true}
modalType={ innerModalType }
/> />
} }
...@@ -375,7 +402,7 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => { ...@@ -375,7 +402,7 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
) )
case 'video': case 'video':
return ( 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': case 'image':
return ( return (
...@@ -383,7 +410,7 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => { ...@@ -383,7 +410,7 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
) )
case 'file': case 'file':
return ( return (
<Fragment>{ getUploader({ accept: '*' }) }</Fragment> <Fragment>{ getUploader({ accept: '*', afterParams: ['no_convert=1'] }) }</Fragment>
) )
default: default:
return <div>Пусто</div> return <div>Пусто</div>
...@@ -461,11 +488,19 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => { ...@@ -461,11 +488,19 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
<div className={"atma-editor-bubble"} onClick={e => e.stopPropagation()}> <div className={"atma-editor-bubble"} onClick={e => e.stopPropagation()}>
{ {
colorsSelected !== null ? colorsSelected !== null ?
colors.map((itemColor, i) => { colors[colorsSelected].map((itemColor, i) => {
return ( <div key={'colors' + i} className={'qcolors'} style={{ background: itemColor}} onClick={()=>{ 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' ? colorsSelected === 'color' ?
editor.chain().focus().unsetHighlight().setColor(itemColor).run() : editor.chain().focus().unsetHighlight().setColor(itemColor).run() :
editor.chain().focus().unsetColor().toggleHighlight({ color: itemColor }).run() editor.chain().focus().unsetColor().toggleHighlight({ color: itemColor }).run();
}
setColorsSelected(null); setColorsSelected(null);
}} /> ) }} /> )
}) : bubbleItems.map((type, i) => { }) : bubbleItems.map((type, i) => {
...@@ -564,19 +599,23 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => { ...@@ -564,19 +599,23 @@ const QEditor = ({ value, onChange = ()=>{}, style, uploadOptions }) => {
break break
case 'file': case 'file':
console.log(uploadedPaths, 'ejkwnferiugnuierwnguirne');
uploadedPaths.map((file, i) => { uploadedPaths.map((file, i) => {
console.log(file);
editor editor
.chain().focus() .chain().focus()
.extendMarkRange('link').setLink({ // .extendMarkRange('link').setLink({
href: file.path, // href: file.path,
target: '_blank', // target: '_blank',
download: true, // download: true,
'data-size': '100 кб' // 'data-size': file.size
}) // })
.insertContent('Example Text') .insertContent(`<a href="${file.path}" target="_blank" download="true" data-size="${file.size}">${file.name}</a>`)
.run(); .run();
}); });
break break
} }
......
...@@ -46,7 +46,7 @@ const ToolBar = ({ editor, toolsLib = [] }) => { ...@@ -46,7 +46,7 @@ const ToolBar = ({ editor, toolsLib = [] }) => {
type: 'g', type: 'g',
items: [ items: [
'link', 'link',
// 'file', 'file',
'image', 'image',
'video', 'video',
'iframe', 'iframe',
...@@ -95,6 +95,29 @@ const ToolBar = ({ editor, toolsLib = [] }) => { ...@@ -95,6 +95,29 @@ const ToolBar = ({ editor, toolsLib = [] }) => {
return editor.isActive(type); 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) => { const getItem = (type = null, idx, isTitle = false) => {
let item = null; let item = null;
...@@ -116,7 +139,7 @@ const ToolBar = ({ editor, toolsLib = [] }) => { ...@@ -116,7 +139,7 @@ const ToolBar = ({ editor, toolsLib = [] }) => {
e.stopPropagation() e.stopPropagation()
return false; 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> <Fragment>
<div className={`qicon q${type}`} /> <div className={`qicon q${type}`} />
......
...@@ -35,9 +35,9 @@ export default class Uploader extends React.Component { ...@@ -35,9 +35,9 @@ export default class Uploader extends React.Component {
this.files = {}; this.files = {};
} }
componentDidUpdate (prevProps, prevState, snapshot) { // componentDidUpdate (prevProps, prevState, snapshot) {
console.log(this.state.files); // console.log(this.state.files);
} // }
get action () { get action () {
return this.props.action; return this.props.action;
...@@ -67,6 +67,10 @@ export default class Uploader extends React.Component { ...@@ -67,6 +67,10 @@ export default class Uploader extends React.Component {
return this.props.errorMessage; return this.props.errorMessage;
} }
get modalType () {
return this.props.modalType;
}
mediaItem(){ mediaItem(){
} }
...@@ -109,8 +113,9 @@ export default class Uploader extends React.Component { ...@@ -109,8 +113,9 @@ export default class Uploader extends React.Component {
{ {
Object.keys(this.state.files).map((uid, i) => ( Object.keys(this.state.files).map((uid, i) => (
<div <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})` }} 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 }) } /> <div className={'atma-editor-uploader-uitems-del'} title={'Удалить'} onClick={()=> this.abortUpload({ uid }) } />
{ {
...@@ -122,6 +127,7 @@ export default class Uploader extends React.Component { ...@@ -122,6 +127,7 @@ export default class Uploader extends React.Component {
</div> </div>
) : null ) : null
} }
{ this.modalType === 'file' && <span>{ this.state.files[uid].name }</span> }
</div> </div>
)) ))
} }
...@@ -150,11 +156,20 @@ export default class Uploader extends React.Component { ...@@ -150,11 +156,20 @@ export default class Uploader extends React.Component {
curFile['uploaded'] = true; curFile['uploaded'] = true;
curFile['path'] = resp.poster || resp.file_path; curFile['path'] = resp.poster || resp.file_path;
curFile['name'] = resp.file_name;
curFile['size'] = resp.file_size;
this.setState({ this.setState({
uploaderSuccess: true, uploaderSuccess: true,
isUpload: false, isUpload: false,
disabledFileUpload: false disabledFileUpload: false,
}, () => this.onSuccess({path: resp.file_path, uid: file.uid})) 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 = { ...@@ -188,4 +203,5 @@ Uploader.defaultProps = {
type: '', type: '',
onSuccess: ()=>{}, onSuccess: ()=>{},
errorMessage: null, errorMessage: null,
modalType: null
}; };
...@@ -359,6 +359,20 @@ body{ ...@@ -359,6 +359,20 @@ body{
background-size: cover; background-size: cover;
background-position: center; background-position: center;
aspect-ratio: 16 / 9; 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{ &-del{
...@@ -381,6 +395,8 @@ body{ ...@@ -381,6 +395,8 @@ body{
} }
} }
} }
&-progress{ &-progress{
...@@ -691,6 +707,23 @@ body{ ...@@ -691,6 +707,23 @@ body{
&:hover{ &:hover{
cursor: pointer; 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{ .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