Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Genesys PGR
Genesys Website
Commits
b1be24a7
Commit
b1be24a7
authored
Nov 06, 2018
by
Maxym Borodenko
Committed by
Matija Obreza
Nov 09, 2018
Browse files
Fix: pasting image instead of text from Word on Mac OS
- Paste Markdown from Word
parent
5a49140c
Changes
8
Hide whitespace changes
Inline
Side-by-side
locales/en/common.json
View file @
b1be24a7
...
...
@@ -73,7 +73,11 @@
"title"
:
"Title"
,
"true"
:
"True"
,
"UUID"
:
"UUID"
,
"yes"
:
"Yes"
"yes"
:
"Yes"
,
"basicMarkdown"
:
"Basic markdown supported"
,
"fullMarkdown"
:
"Full markdown supported"
,
"previewMarkdown"
:
"Preview markdown"
,
"editMarkdown"
:
"Edit Markdown"
},
"paginate"
:
{
"numberOfItems"
:
"{{count, number}} {{what, lowercase}}"
,
...
...
src/actions/repository.ts
0 → 100644
View file @
b1be24a7
import
RepositoryFile
from
'
model/repository/RepositoryFile
'
;
import
RepositoryService
from
'
service/genesys/RepositoryService
'
;
import
{
log
}
from
'
utilities/debug
'
;
import
*
as
UUIDv4
from
'
uuid/v4
'
;
export
const
uploadMarkdownAttachment
=
(
file
:
File
)
=>
(
dispatch
,
getState
)
=>
{
const
metadata
:
RepositoryFile
=
new
RepositoryFile
();
const
dummy
:
string
=
UUIDv4
().
replace
(
/
\-
/g
,
''
);
metadata
.
originalFilename
=
`
${
dummy
}
_
${
file
.
name
}
`
;
metadata
.
contentType
=
file
.
type
;
console
.
log
(
`Uploading Markdown`
,
metadata
);
return
RepositoryService
.
uploadFile
(
'
/content/markdown
'
,
file
,
metadata
)
.
then
((
repoFile
:
RepositoryFile
)
=>
{
return
repoFile
;
}).
catch
((
error
)
=>
{
log
(
'
Upload error
'
,
error
);
});
};
src/requests/ui/admin/DisplayPage.tsx
View file @
b1be24a7
...
...
@@ -17,7 +17,7 @@ import Loading from 'ui/common/Loading';
import
PrettyDate
from
'
ui/common/time/PrettyDate
'
;
import
ActionButton
from
'
ui/common/buttons/ActionButton
'
;
import
BackButton
from
'
ui/common/buttons/BackButton
'
;
import
Markdown
from
'
ui/c
atalog
/markdown
'
;
import
Markdown
from
'
ui/c
ommon
/markdown
'
;
interface
IDisplayPageProps
extends
React
.
ClassAttributes
<
any
>
{
t
:
any
;
...
...
src/service/genesys/RepositoryService.ts
View file @
b1be24a7
...
...
@@ -277,10 +277,8 @@ class FileRepositoryService {
// console.log(`Fetching from ${apiUrl}`);
const
data
=
new
FormData
();
data
.
append
(
'
file
'
,
file
);
if
(
metadata
)
{
data
.
append
(
'
metadata
'
,
JSON
.
stringify
(
metadata
));
}
// data.append('metadata', new Blob([ JSON.stringify(metadata) ], { type : 'application/json' }));
// data.append('metadata', JSON.stringify(metadata));
data
.
append
(
'
metadata
'
,
new
Blob
([
JSON
.
stringify
(
metadata
)
],
{
type
:
'
application/json
'
}));
const
content
=
{
data
};
return
axiosBackend
.
request
({
...
...
src/subsets/ui/dashboard/subset-stepper/steps/basic-info/BasicInfoForm.tsx
View file @
b1be24a7
...
...
@@ -6,7 +6,7 @@ import {SUBSET_FORM} from 'subsets/constants';
import
Validators
from
'
utilities/Validators
'
;
import
{
TextField
}
from
'
ui/common/text-field
'
;
import
MarkdownField
from
'
ui/common/markdown/MarkdownField
'
;
import
{
MarkdownField
WithAttach
}
from
'
ui/common/markdown/MarkdownField
WithAttach
'
;
import
CropSelector
from
'
crop/ui/c/CropSelector
'
;
interface
ILoginContainerProps
extends
React
.
ClassAttributes
<
any
>
{
...
...
@@ -43,7 +43,7 @@ class BasicInfoStep extends React.Component<ILoginContainerProps, any> {
/>
<
Field
name
=
"description"
component
=
{
MarkdownField
}
component
=
{
MarkdownField
WithAttach
}
label
=
{
t
(
'
subsets.dashboard.p.stepper.basicInfo.subsetDescription
'
)
}
placeholder
=
{
t
(
'
subsets.dashboard.p.stepper.basicInfo.subsetDescriptionPlaceholder
'
)
}
/>
...
...
src/ui/catalog/markdown/index.tsx
deleted
100644 → 0
View file @
5a49140c
import
*
as
React
from
'
react
'
;
import
{
bindActionCreators
}
from
'
redux
'
;
import
{
connect
}
from
'
react-redux
'
;
import
Markdown
from
'
ui/common/markdown
'
;
import
OriginalMarkdownField
from
'
ui/common/markdown/MarkdownField
'
;
import
FormControl
from
'
ui/common/forms/FormControl
'
;
import
Input
from
'
@material-ui/core/Input
'
;
import
FormHelperText
from
'
@material-ui/core/FormHelperText
'
;
class
MarkdownField
extends
OriginalMarkdownField
{
// ref to input textarea
private
noReactUpdates
:
boolean
=
false
;
public
constructor
(
props
:
any
)
{
super
(
props
);
this
.
stopReactUpdate
=
this
.
stopReactUpdate
.
bind
(
this
);
this
.
resumeReactUpdate
=
this
.
resumeReactUpdate
.
bind
(
this
);
}
private
stopReactUpdate
=
()
=>
{
console
.
log
(
'
Stopping React updates
'
);
this
.
noReactUpdates
=
true
;
}
private
resumeReactUpdate
=
()
=>
{
console
.
log
(
'
Resuming React updates
'
);
this
.
noReactUpdates
=
false
;
}
// We need to use this while dragging so that component is not rerendered
public
shouldComponentUpdate
(
nextProps
,
nextState
)
{
// console.log(`shouldComponentUpdate ${! this.noReactUpdates}`); // , this.props, nextProps, this.state, nextState);
return
!
this
.
noReactUpdates
;
}
public
render
()
{
const
{
classes
,
basicMarkdown
,
input
,
label
,
required
,
meta
,
meta
:
{
touched
,
error
},
...
custom
}
=
this
.
props
;
const
basic
:
boolean
=
basicMarkdown
===
undefined
||
null
?
false
:
basicMarkdown
;
if
(
basic
)
{
return
(
<
FormControl
fullWidth
required
=
{
required
}
meta
=
{
meta
}
label
=
{
label
}
>
<
Input
error
=
{
touched
&&
error
}
{
...
input
}
{
...
custom
}
/>
<
FormHelperText
>
<
span
>
Basic markdown supported: * **
</
span
>
</
FormHelperText
>
</
FormControl
>
);
}
return
(
<
div
>
{
!
this
.
state
.
previewMode
?
<
FormControl
fullWidth
required
=
{
required
}
meta
=
{
meta
}
label
=
{
label
}
>
<
Input
error
=
{
touched
&&
error
}
multiline
{
...
input
}
{
...
custom
}
/>
<
FormHelperText
><
a
onClick
=
{
this
.
onChangePreviewMode
}
>
Preview Markdown
</
a
>
<
span
>
Full markdown supported
</
span
></
FormHelperText
>
</
FormControl
>
:
<
FormControl
fullWidth
required
=
{
required
}
meta
=
{
meta
}
label
=
{
label
}
>
<
div
style
=
{
{
paddingTop
:
'
1.5rem
'
}
}
>
<
Markdown
source
=
{
input
.
value
}
/>
</
div
>
<
FormHelperText
><
a
onClick
=
{
this
.
onChangePreviewMode
}
>
Edit Markdown
</
a
></
FormHelperText
>
</
FormControl
>
}
</
div
>
);
}
}
const
mapDispatchToProps
=
(
dispatch
)
=>
bindActionCreators
({
},
dispatch
);
const
_markdownField
=
connect
(
null
,
mapDispatchToProps
)(
MarkdownField
);
export
{
Markdown
as
default
,
_markdownField
as
MarkdownField
};
src/ui/common/markdown/MarkdownFieldWithAttach.tsx
0 → 100644
View file @
b1be24a7
import
*
as
React
from
'
react
'
;
import
{
bindActionCreators
}
from
'
redux
'
;
import
{
connect
}
from
'
react-redux
'
;
import
{
translate
}
from
'
react-i18next
'
;
import
{
uploadMarkdownAttachment
}
from
'
actions/repository
'
;
import
Markdown
from
'
ui/common/markdown
'
;
import
OriginalMarkdownField
from
'
ui/common/markdown/MarkdownField
'
;
import
FormControl
from
'
ui/common/forms/FormControl
'
;
import
Input
from
'
@material-ui/core/Input
'
;
import
FormHelperText
from
'
@material-ui/core/FormHelperText
'
;
import
{
insertAtCaret
}
from
'
utilities
'
;
class
MarkdownField
extends
OriginalMarkdownField
{
// ref to input textarea
private
textarea
:
any
;
private
noReactUpdates
:
boolean
=
false
;
public
constructor
(
props
:
any
)
{
super
(
props
);
this
.
setRef
=
this
.
setRef
.
bind
(
this
);
this
.
dataDropped
=
this
.
dataDropped
.
bind
(
this
);
this
.
dataPasted
=
this
.
dataPasted
.
bind
(
this
);
this
.
stopReactUpdate
=
this
.
stopReactUpdate
.
bind
(
this
);
this
.
resumeReactUpdate
=
this
.
resumeReactUpdate
.
bind
(
this
);
}
// Bind event listeners
private
setRef
=
(
textarea
):
void
=>
{
this
.
textarea
=
textarea
;
if
(
textarea
)
{
this
.
textarea
.
addEventListener
(
'
drop
'
,
this
.
dataDropped
,
false
);
this
.
textarea
.
addEventListener
(
'
dragenter
'
,
this
.
stopReactUpdate
,
false
);
this
.
textarea
.
addEventListener
(
'
dragexit
'
,
this
.
resumeReactUpdate
,
false
);
this
.
textarea
.
addEventListener
(
'
paste
'
,
this
.
dataPasted
,
false
);
}
}
// Unbind event listeners
public
componentWillUnmount
()
{
if
(
this
.
textarea
)
{
this
.
textarea
.
removeEventListener
(
'
drop
'
,
this
.
dataDropped
,
false
);
this
.
textarea
.
removeEventListener
(
'
dragenter
'
,
this
.
stopReactUpdate
,
false
);
this
.
textarea
.
removeEventListener
(
'
dragexit
'
,
this
.
resumeReactUpdate
,
false
);
this
.
textarea
.
removeEventListener
(
'
paste
'
,
this
.
dataPasted
,
false
);
}
}
private
stopReactUpdate
=
()
=>
{
console
.
log
(
'
Stopping React updates
'
);
this
.
noReactUpdates
=
true
;
}
private
resumeReactUpdate
=
()
=>
{
console
.
log
(
'
Resuming React updates
'
);
this
.
noReactUpdates
=
false
;
}
private
dataDropped
=
(
e
)
=>
{
const
{
input
}
=
this
.
props
;
e
.
preventDefault
();
const
{
dataTransfer
:
{
items
,
files
}
}
=
e
;
const
list
=
[
...
items
].
filter
((
i
)
=>
i
.
kind
===
'
file
'
).
map
((
i
)
=>
i
.
getAsFile
())
||
files
;
const
p
=
[];
for
(
const
f
of
list
)
{
const
result
=
this
.
addFile
(
f
);
p
.
push
(
result
);
}
Promise
.
all
(
p
).
then
(()
=>
{
input
.
onChange
(
this
.
textarea
.
value
);
this
.
resumeReactUpdate
();
});
}
private
dataPasted
=
async
(
e
)
=>
{
const
{
clipboardData
:
{
files
}
}
=
e
;
const
types
:
string
[]
=
e
.
clipboardData
.
types
;
if
(
files
.
length
&&
(
types
.
indexOf
(
'
text/plain
'
)
===
-
1
))
{
e
.
preventDefault
();
for
(
const
f
of
files
)
{
await
this
.
addFile
(
f
);
}
}
else
{
// NOOP
}
}
private
addFile
=
(
file
:
File
)
=>
{
const
{
uploadMarkdownAttachment
}
=
this
.
props
;
const
textarea
=
this
.
textarea
;
// only trigger the upload in case of a real picture
if
(
!
file
.
type
.
startsWith
(
'
image/
'
))
{
return
;
}
return
uploadMarkdownAttachment
(
file
)
.
then
((
r
)
=>
{
if
(
r
.
contentType
.
startsWith
(
'
image/
'
))
{
insertAtCaret
(
textarea
,
``
);
}
else
{
insertAtCaret
(
textarea
,
`[
${
file
.
name
}
](/proxy/uploads/
${
r
.
uuid
}
)`
);
}
return
r
;
});
}
// We need to use this while dragging so that component is not rerendered
public
shouldComponentUpdate
(
nextProps
,
nextState
)
{
return
!
this
.
noReactUpdates
;
}
public
render
()
{
const
{
classes
,
t
,
basicMarkdown
,
input
,
label
,
required
,
meta
,
...
custom
}
=
this
.
props
;
const
basic
:
boolean
=
basicMarkdown
===
undefined
||
null
?
false
:
basicMarkdown
;
if
(
basic
)
{
return
(
<
FormControl
fullWidth
required
=
{
required
}
meta
=
{
meta
}
label
=
{
label
}
>
<
Input
error
=
{
meta
&&
meta
.
touched
&&
meta
.
error
}
{
...
input
}
{
...
custom
}
/>
<
FormHelperText
>
<
span
>
{
t
(
'
common:label.basicMarkdown
'
)
}
:
<
code
>
*
</
code
>
<
code
>
**
</
code
></
span
>
</
FormHelperText
>
</
FormControl
>
);
}
return
(
<
div
>
{
!
this
.
state
.
previewMode
?
<
FormControl
fullWidth
required
=
{
required
}
meta
=
{
meta
}
label
=
{
label
}
>
<
Input
error
=
{
meta
&&
meta
.
touched
&&
meta
.
error
}
inputRef
=
{
this
.
setRef
}
multiline
{
...
input
}
{
...
custom
}
/>
<
FormHelperText
>
<
a
onClick
=
{
this
.
onChangePreviewMode
}
>
{
t
(
'
common:label.previewMarkdown
'
)
}
</
a
>
<
span
>
{
t
(
'
common:label.fullMarkdown
'
)
}
</
span
>
</
FormHelperText
>
</
FormControl
>
:
<
FormControl
fullWidth
required
=
{
required
}
meta
=
{
meta
}
label
=
{
label
}
>
<
div
style
=
{
{
paddingTop
:
'
1.5rem
'
}
}
>
<
Markdown
source
=
{
input
.
value
}
/>
</
div
>
<
FormHelperText
><
a
onClick
=
{
this
.
onChangePreviewMode
}
>
{
t
(
'
common:label.editMarkdown
'
)
}
</
a
></
FormHelperText
>
</
FormControl
>
}
</
div
>
);
}
}
const
mapDispatchToProps
=
(
dispatch
)
=>
bindActionCreators
({
uploadMarkdownAttachment
,
},
dispatch
);
export
const
MarkdownFieldWithAttach
=
translate
()(
connect
(
null
,
mapDispatchToProps
)(
MarkdownField
));
src/ui/pages/welcome/index.tsx
View file @
b1be24a7
...
...
@@ -8,7 +8,7 @@ import { navigateTo } from 'actions/navigation';
import
ContentHeader
from
'
ui/common/heading/ContentHeader
'
;
import
Grid
from
'
@material-ui/core/Grid
'
;
import
Markdown
from
'
ui/c
atalog
/markdown
'
;
import
Markdown
from
'
ui/c
ommon
/markdown
'
;
import
{
Link
}
from
'
react-router-dom
'
;
import
Input
from
'
@material-ui/core/Input
'
;
import
InputAdornment
from
'
@material-ui/core/InputAdornment
'
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment