[CORL-436] Embed Code (#2398)

* feat: initial implementation

* fix: moved embed configuration to advanced

* feat: added copy button to embed code

* fix: removing unused line
This commit is contained in:
Wyatt Johnson
2019-07-12 22:35:09 +00:00
committed by GitHub
parent bc0b0d0339
commit d312d380ae
15 changed files with 214 additions and 14 deletions
+7 -2
View File
@@ -3541,6 +3541,12 @@
"commander": "*"
}
},
"@types/common-tags": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@types/common-tags/-/common-tags-1.8.0.tgz",
"integrity": "sha512-htRqZr5qn8EzMelhX/Xmx142z218lLyGaeZ3YR8jlze4TATRU9huKKvuBmAJEW4LCC4pnY1N6JAm6p85fMHjhg==",
"dev": true
},
"@types/compression-webpack-plugin": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/compression-webpack-plugin/-/compression-webpack-plugin-2.0.0.tgz",
@@ -7992,8 +7998,7 @@
"common-tags": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz",
"integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==",
"dev": true
"integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw=="
},
"commondir": {
"version": "1.0.1",
+2
View File
@@ -60,6 +60,7 @@
"bull": "^3.8.1",
"bunyan": "^1.8.12",
"cheerio": "^1.0.0-rc.2",
"common-tags": "^1.8.0",
"consolidate": "0.14.0",
"content-security-policy-builder": "^2.0.0",
"convict": "^4.3.1",
@@ -152,6 +153,7 @@
"@types/cheerio": "^0.22.8",
"@types/classnames": "^2.2.7",
"@types/commander": "^2.12.2",
"@types/common-tags": "^1.8.0",
"@types/compression-webpack-plugin": "^2.0.0",
"@types/consolidate": "0.0.34",
"@types/convict": "^4.2.0",
@@ -5,6 +5,7 @@ import { HorizontalGutter } from "coral-ui/components";
import CommentStreamLiveUpdatesContainer from "./CommentStreamLiveUpdatesContainer";
import CustomCSSConfigContainer from "./CustomCSSConfigContainer";
import EmbedCodeContainer from "./EmbedCodeContainer";
import PermittedDomainsConfigContainer from "./PermittedDomainsConfigContainer";
interface Props {
@@ -12,7 +13,8 @@ interface Props {
settings: PropTypesOf<typeof CustomCSSConfigContainer>["settings"] &
PropTypesOf<typeof PermittedDomainsConfigContainer>["settings"] &
PropTypesOf<typeof CommentStreamLiveUpdatesContainer>["settings"] &
PropTypesOf<typeof CommentStreamLiveUpdatesContainer>["settingsReadOnly"];
PropTypesOf<typeof CommentStreamLiveUpdatesContainer>["settingsReadOnly"] &
PropTypesOf<typeof EmbedCodeContainer>["settings"];
onInitValues: (values: any) => void;
}
@@ -22,6 +24,7 @@ const AdvancedConfig: FunctionComponent<Props> = ({
onInitValues,
}) => (
<HorizontalGutter size="double" data-testid="configure-advancedContainer">
<EmbedCodeContainer settings={settings} />
<CustomCSSConfigContainer
disabled={disabled}
settings={settings}
@@ -45,6 +45,7 @@ class AdvancedConfigContainer extends React.Component<Props> {
const enhanced = withFragmentContainer<Props>({
settings: graphql`
fragment AdvancedConfigContainer_settings on Settings {
...EmbedCodeContainer_settings
...CustomCSSConfigContainer_settings
...PermittedDomainsConfigContainer_settings
...CommentStreamLiveUpdatesContainer_settings
@@ -0,0 +1,10 @@
.textArea {
width: 100%;
box-sizing: border-box;
padding: calc(0.5 * var(--mini-unit));
resize: none;
}
.copyArea {
text-align: right;
}
@@ -0,0 +1,80 @@
import { stripIndent } from "common-tags";
import { Localized } from "fluent-react/compat";
import React, { FunctionComponent, useMemo } from "react";
import { getLocationOrigin } from "coral-common/utils";
import { CopyButton } from "coral-framework/components";
import { HorizontalGutter, Typography } from "coral-ui/components";
import Header from "../../Header";
import styles from "./EmbedCode.css";
interface Props {
staticURI: string | null;
}
const EmbedCode: FunctionComponent<Props> = ({ staticURI }) => {
const embed = useMemo(() => {
// Get the origin of the current page.
const origin = getLocationOrigin();
// Optionally use the staticURI for configuration.
const script = staticURI || origin;
// Return the HTML template.
const text = stripIndent`
<div id="coral_thread"></div>
<script type="text/javascript">
(function() {
var d = document, s = d.createElement('script');
s.src = '${script}/assets/js/embed.js';
s.onload = function() {
Coral.createStreamEmbed({
id: "coral_thread",
autoRender: true,
rootURL: '${origin}',
// Comment these out and replace with the ID of the
// story's ID and URL from your CMS to provide the
// tightest integration. Refer to our documentation at
// https://docs.coralproject.net for all the configuration
// options.
// storyID: '\${storyID}',
// storyURL: '\${storyURL}',
});
};
(d.head || d.body).appendChild(s);
})();
</script>`;
// Count the number of rows in the embed code.
const rows = text.split(/\r\n|\r|\n/).length;
return { text, rows };
}, [staticURI]);
return (
<HorizontalGutter size="oneAndAHalf" container="fieldset">
<Localized id="configure-advanced-embedCode-title">
<Header container="legend">Embed Code</Header>
</Localized>
<Localized id="configure-advanced-embedCode-explanation">
<Typography variant="detail">
Copy and paste the code below into your CMS to embed Coral comment
streams in each of your sites stories.
</Typography>
</Localized>
<textarea
rows={embed.rows}
className={styles.textArea}
readOnly
value={embed.text}
/>
<HorizontalGutter className={styles.copyArea}>
<CopyButton size="regular" text={embed.text} />
</HorizontalGutter>
</HorizontalGutter>
);
};
export default EmbedCode;
@@ -0,0 +1,25 @@
import React, { FunctionComponent } from "react";
import { graphql } from "react-relay";
import { EmbedCodeContainer_settings } from "coral-admin/__generated__/EmbedCodeContainer_settings.graphql";
import { withFragmentContainer } from "coral-framework/lib/relay";
import EmbedCode from "./EmbedCode";
interface Props {
settings: EmbedCodeContainer_settings;
}
const EmbedCodeContainer: FunctionComponent<Props> = ({ settings }) => {
return <EmbedCode staticURI={settings.staticURI} />;
};
const enhanced = withFragmentContainer<Props>({
settings: graphql`
fragment EmbedCodeContainer_settings on Settings {
staticURI
}
`,
})(EmbedCodeContainer);
export default enhanced;
@@ -107,6 +107,66 @@ exports[`renders configure advanced 1`] = `
className="Box-root HorizontalGutter-root HorizontalGutter-double"
data-testid="configure-advancedContainer"
>
<fieldset
className="Box-root HorizontalGutter-root HorizontalGutter-oneAndAHalf"
>
<legend
className="Box-root Typography-root Typography-heading1 Typography-colorTextPrimary Header-root"
>
Embed Code
</legend>
<p
className="Box-root Typography-root Typography-detail Typography-colorTextPrimary"
>
Copy and paste the code below into your CMS to embed Coral comment streams in
each of your sites stories.
</p>
<textarea
className="EmbedCode-textArea"
readOnly={true}
rows={22}
value="<div id=\\"coral_thread\\"></div>
<script type=\\"text/javascript\\">
(function() {
var d = document, s = d.createElement('script');
s.src = 'http://localhost/assets/js/embed.js';
s.onload = function() {
Coral.createStreamEmbed({
id: \\"coral_thread\\",
autoRender: true,
rootURL: 'http://localhost',
// Comment these out and replace with the ID of the
// story's ID and URL from your CMS to provide the
// tightest integration. Refer to our documentation at
// https://docs.coralproject.net for all the configuration
// options.
// storyID: '\${storyID}',
// storyURL: '\${storyURL}',
});
};
(d.head || d.body).appendChild(s);
})();
</script>"
/>
<div
className="Box-root HorizontalGutter-root EmbedCode-copyArea HorizontalGutter-full"
>
<button
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
onTouchEnd={[Function]}
type="button"
>
<span>
Copy
</span>
</button>
</div>
</fieldset>
<div
className="Box-root HorizontalGutter-root FormField-root HorizontalGutter-half"
>
+1 -10
View File
@@ -1,6 +1,6 @@
import { EventEmitter2 } from "eventemitter2";
import { parseQuery } from "coral-common/utils";
import { getLocationOrigin, parseQuery } from "coral-common/utils";
import { default as create, StreamEmbed } from "./StreamEmbed";
@@ -15,15 +15,6 @@ export interface Config {
accessToken?: string;
}
function getLocationOrigin() {
return (
location.origin ||
`${window.location.protocol}//${window.location.hostname}${
window.location.port ? `:${window.location.port}` : ""
}`
);
}
function resolveStoryURL() {
const canonical = document.querySelector(
'link[rel="canonical"]'
@@ -0,0 +1,5 @@
export default function getLocationOrigin() {
return (
location.origin || `${window.location.protocol}//${window.location.host}`
);
}
+1
View File
@@ -8,3 +8,4 @@ export { default as ensureNoEndSlash } from "./ensureNoEndSlash";
export { default as parseQuery } from "./parseQuery";
export { default as stringifyQuery } from "./stringifyQuery";
export { default as pureMerge } from "./pureMerge";
export { default as getLocationOrigin } from "./getLocationOrigin";
+1 -1
View File
@@ -170,7 +170,7 @@ const config = convict({
format: "optional-url",
default: "",
env: "STATIC_URI",
arg: "staticUri",
arg: "staticURI",
},
websocket_keep_alive_timeout: {
doc:
@@ -0,0 +1,6 @@
import { GQLSettingsTypeResolver } from "coral-server/graph/tenant/schema/__generated__/types";
import { Tenant } from "coral-server/models/tenant";
export const Settings: GQLSettingsTypeResolver<Tenant> = {
staticURI: (tenant, args, ctx) => ctx.config.get("static_uri") || null,
};
@@ -1076,6 +1076,11 @@ type Settings {
"""
domain: String! @auth(roles: [ADMIN])
"""
staticURI if configured, is the static URI used to serve static files from.
"""
staticURI: String @auth(roles: [ADMIN])
"""
allowedDomains is the list of domains that stories can come from.
"""
+6
View File
@@ -296,6 +296,7 @@ configure-wordList-suspect-wordListDetail =
configure-advanced-customCSS = Custom CSS
configure-advanced-customCSS-explanation =
URL of a CSS stylesheet that will override default Embed Stream styles. Can be internal or external.
configure-advanced-permittedDomains = Permitted Domains
configure-advanced-permittedDomains-explanation =
Domains where your { -product-name } instance is allowed to be embedded.
@@ -306,6 +307,11 @@ configure-advanced-liveUpdates = Comment Stream Live Updates
configure-advanced-liveUpdates-explanation =
When enabled, there will be real-time loading and updating of comments as new comments and replies are published
configure-advanced-embedCode-title = Embed Code
configure-advanced-embedCode-explanation =
Copy and paste the code below into your CMS to embed Coral comment streams in
each of your sites stories.
## Decision History
decisionHistory-popover =
.description = A dialog showing the decision history