Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull quote improvements #4246

Merged
merged 6 commits into from
Jun 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import {includes} from 'lodash';
import {getLabelForFieldId} from '../../helpers/getLabelForFieldId';
import {appConfig} from 'appConfig';
import {IArticleField, FORMATTING_OPTION, RICH_FORMATTING_OPTION} from 'superdesk-api';
import {gettext} from 'core/utils';

interface IScope extends ng.IScope {
getEditor3FormattingOptions: (fieldName: string) => Array<string>;
getEditor3FormattingOptions: (fieldName: string) => Dictionary<string, string>;
model: any;
fields: {[key: string]: IArticleField};
form: any;
formattingOptions: Array<string>;
formattingOptions: Dictionary<FORMATTING_OPTION, string>;
schemaKeysOrdering: any;
schemaKeysDisabled: any;
characterValidationEnabled: boolean;
Expand All @@ -17,6 +18,7 @@ interface IScope extends ng.IScope {
label(id): string;
remove(key: string): void;
toggle(schema: { key: string; }, key: string, position: 'before' | 'after'): void;
onChange(value: Array<string>, fieldId: string): void;
reorder(start: number, end: number, key: string): void;
setDirty(): void;
updateOrder(key?: any): void;
Expand All @@ -31,98 +33,105 @@ const HAS_PLAINTEXT_FORMATTING_OPTIONS = Object.freeze({
headline: true,
});

const HAS_RICH_FORMATTING_OPTIONS = Object.freeze({
export const HAS_RICH_FORMATTING_OPTIONS = Object.freeze({
abstract: true,
body_html: true,
footer: true,
body_footer: true,
});

const FORMATTING_OPTIONS: Array<FORMATTING_OPTION> = [
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'justifyLeft',
'justifyCenter',
'justifyRight',
'justifyFull',
'outdent',
'indent',
'unordered list',
'ordered list',
'pre',
'quote',
'media',
'link',
'superscript',
'subscript',
'strikethrough',
'underline',
'italic',
'bold',
'table',
'multi-line quote',
];
const getFormattingOptions = (): Dictionary<FORMATTING_OPTION, string> => {
return {
'h1': gettext('h1'),
'h2': gettext('h2'),
'h3': gettext('h3'),
'h4': gettext('h4'),
'h5': gettext('h5'),
'h6': gettext('h6'),
'justifyLeft': gettext('justifyLeft'),
'justifyCenter': gettext('justifyCenter'),
'justifyRight': gettext('justifyRight'),
'justifyFull': gettext('justifyFull'),
'outdent': gettext('outdent'),
'indent': gettext('indent'),
'unordered list': gettext('h1'),
'ordered list': gettext('unordered list'),
'pre': gettext('pre'),
'quote': gettext('quote'),
'media': gettext('media'),
'link': gettext('link'),
'superscript': gettext('superscript'),
'subscript': gettext('subscript'),
'strikethrough': gettext('strikethrough'),
'underline': gettext('underline'),
'italic': gettext('italic'),
'bold': gettext('bold'),
'table': gettext('table'),
'multi-line quote': gettext('multi-line quote'),
};
};

export type PLAINTEXT_FORMATTING_OPTION = 'uppercase' | 'lowercase';

const EDITOR3_PLAINTEXT_FORMATTING_OPTIONS: Array<PLAINTEXT_FORMATTING_OPTION> = [
'uppercase',
'lowercase',
];
export const getEditor3PlainTextFormattingOptions = (): Dictionary<PLAINTEXT_FORMATTING_OPTION, string> => ({
'uppercase': gettext('uppercase'),
'lowercase': gettext('lowercase'),
});

export const formattingOptionsUnsafeToParseFromHTML: Array<RICH_FORMATTING_OPTION> = [
export const getFormattingOptionsUnsafeToParseFromHTML = (): Dictionary<RICH_FORMATTING_OPTION, string> => ({
// these aren't outputted to HTML at all
'comments',
'suggestions',
'comments': gettext('comments'),
'suggestions': gettext('suggestions'),

// no standard in HTML, parsing according to our output format is not implemented
'annotation',
'annotation': gettext('annotation'),

// may not be parsed well
'pre',
'embed',
'media',
'table',
];

const EDITOR3_RICH_FORMATTING_OPTIONS: Array<RICH_FORMATTING_OPTION> = [
...EDITOR3_PLAINTEXT_FORMATTING_OPTIONS,
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'ordered list',
'unordered list',
'quote',
'media',
'link',
'embed',
'underline',
'italic',
'bold',
'table',
'formatting marks',
'remove format',
'remove all format',
'annotation',
'comments',
'suggestions',
'pre',
'superscript',
'subscript',
'strikethrough',
'tab',
'tab as spaces',
'undo',
'redo',
'multi-line quote',
];
'pre': gettext('pre'),
'embed': gettext('embed'),
'media': gettext('media'),
'table': gettext('table'),
});

export const getEditor3RichFormattingOptions = (): Dictionary<RICH_FORMATTING_OPTION, string> => ({
...getEditor3PlainTextFormattingOptions(),
'h1': gettext('h1'),
'h2': gettext('h2'),
'h3': gettext('h3'),
'h4': gettext('h4'),
'h5': gettext('h5'),
'h6': gettext('h6'),
'justifyLeft': gettext('justifyLeft'),
'justifyCenter': gettext('justifyCenter'),
'justifyRight': gettext('justifyRight'),
'justifyFull': gettext('justifyFull'),
'outdent': gettext('outdent'),
'indent': gettext('indent'),
'unordered list': gettext('unordered list'),
'ordered list': gettext('ordered list'),
'pre': gettext('pre'),
'quote': gettext('quote'),
'media': gettext('media'),
'link': gettext('link'),
'superscript': gettext('superscript'),
'subscript': gettext('subscript'),
'strikethrough': gettext('strikethrough'),
'underline': gettext('underline'),
'italic': gettext('italic'),
'bold': gettext('bold'),
'table': gettext('table'),
'multi-line quote': gettext('multi-line quote'),
'formatting marks': gettext('formatting marks'),
'remove format': gettext('remove format'),
'remove all format': gettext('remove all format'),
'annotation': gettext('annotation'),
'comments': gettext('comments'),
'suggestions': gettext('suggestions'),
'tab': gettext('tab'),
'tab as spaces': gettext('tab as space'),
'undo': gettext('undo'),
'redo': gettext('redo'),
});

/**
* @ngdoc directive
Expand Down Expand Up @@ -150,17 +159,17 @@ export function ContentProfileSchemaEditor(vocabularies) {
onDrag: '&',
},
link: function(scope: IScope, elem, attr, form) {
scope.formattingOptions = FORMATTING_OPTIONS;
scope.formattingOptions = getFormattingOptions();
scope.characterValidationEnabled = appConfig?.disallowed_characters != null;

scope.getEditor3FormattingOptions = (fieldName) => {
const isCustomPlainTextField = typeof scope.fields[fieldName] === 'object'
&& scope.fields[fieldName].field_type === 'text';

if (Object.keys(HAS_RICH_FORMATTING_OPTIONS).includes(fieldName) || isCustomPlainTextField) {
return EDITOR3_RICH_FORMATTING_OPTIONS;
return getEditor3RichFormattingOptions();
} else {
return EDITOR3_PLAINTEXT_FORMATTING_OPTIONS;
return getEditor3PlainTextFormattingOptions();
}
};

Expand All @@ -184,6 +193,12 @@ export function ContentProfileSchemaEditor(vocabularies) {
scope.setDirty();
};

scope.onChange = (value, fieldId) => {
scope.model.editor[fieldId].formatOptions = value;
scope.setDirty();
scope.$applyAsync();
};

scope.setDirty = () => {
form.$setDirty();
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import {TreeSelect} from 'superdesk-ui-framework/react';
import {
HAS_RICH_FORMATTING_OPTIONS,
getEditor3PlainTextFormattingOptions,
getEditor3RichFormattingOptions,
} from '../directives/ContentProfileSchemaEditor';
import {IArticleField} from 'superdesk-api';

interface IProps {
value: Array<string>;
fieldId: string;
fields: Dictionary<string, IArticleField>;
onChange(value: Array<string>, fieldId: string): void;
}

export class FormattingOptionsTreeSelect extends React.Component<IProps> {
render(): React.ReactNode {
const {fields, fieldId} = this.props;

const isCustomPlainTextField = typeof fields[fieldId] === 'object' && fields[fieldId].field_type === 'text';
const isRichOrCustomTextField =
Object.keys(HAS_RICH_FORMATTING_OPTIONS).includes(fieldId) || isCustomPlainTextField;
const formattingOptions = Object.entries(
isRichOrCustomTextField
? getEditor3RichFormattingOptions()
: getEditor3PlainTextFormattingOptions(),
)
.map(([notTranslatedOption, translatedOption]) => ({value: [notTranslatedOption, translatedOption]}));

const values = formattingOptions
.filter((option) => this.props.value.includes(option.value[0]))
.map((option) => option.value);

return (
<TreeSelect
kind="synchronous"
getId={(option) => option[0]}
getLabel={(option) => option[1]}
getOptions={() => formattingOptions}
onChange={(newFormattingOptions) => {
this.props.onChange(newFormattingOptions.map((option) => option[0]), this.props.fieldId);
}}
value={values}
allowMultiple
fullWidth
labelHidden
inlineLabel
width="100%"
/>
);
}
}
29 changes: 17 additions & 12 deletions scripts/apps/workspace/content/views/schema-editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@

<div class="field">
<label class="" translate>Width</label>
<div class="sd-line-input sd-line-input--is-select sd-line-input--no-label sd-line-input--no-margin">
<div class="sd-line-input sd-line-input--is-select sd-line-input--no-label sd-line-input--no-margin">
<select class="sd-line-input__select" ng-model="model.editor[id].sdWidth">
<option value="full" translate>Full</option>
<option value="half" translate>Half</option>
Expand All @@ -82,21 +82,26 @@
<!-- IF EDITOR3 -->
<div class="field" ng-if="hasFormatOptions(id) && model.editor.body_html.editor3 === true">
<label translate>Format options</label>
<div class="controls" ng-if="model.editor.body_html.editor3"
sd-multi-select
data-item="model.editor[id].formatOptions"
data-list="getEditor3FormattingOptions(id)"
data-change="setDirty()">
</div>
<sd-formatting-options-tree-select
class="controls"
ng-if="model.editor.body_html.editor3"
data-value="model.editor[id].formatOptions"
data-field-id="id"
data-fields="fields"
data-on-change="onChange"
/>
</div>
<!-- ELSE IF EDITOR2 -->
<div class="field" ng-if="hasFormatOptions(id) && model.editor.body_html.editor3 !== true">
<label translate>Format options</label>
<div class="controls" ng-if="!model.editor.body_html.editor3"
sd-multi-select
data-item="model.editor[id].formatOptions"
data-list="formattingOptions"
data-change="setDirty()">
<div
class="controls"
ng-if="!model.editor.body_html.editor3"
sd-multi-select
data-item="model.editor[id].formatOptions"
data-list="formattingOptions"
data-change="setDirty()"
>
</div>
</div>
<!-- END IF -->
Expand Down
18 changes: 17 additions & 1 deletion scripts/core/editor3/components/media/dragable-editor3-block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import {ContentBlock} from 'draft-js';
import {EDITOR_BLOCK_TYPE} from 'core/editor3/constants';
import {connect} from 'react-redux';
import {Spacer} from 'core/ui/components/SubNav/Spacer';

interface IProps {
block: ContentBlock;
Expand All @@ -20,7 +21,22 @@ class DragableEditor3BlockComponent extends React.PureComponent<IProps> {
}
render() {
return (
<div draggable={this.props.readOnly !== true} onDragStart={this.onDragStart}>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: 24,
}}
>
<div
style={{
backgroundColor: 'red',
height: '100px',
width: '10px',
}}
draggable={this.props.readOnly !== true}
onDragStart={this.onDragStart}
/>
{this.props.children}
</div>
);
Expand Down
Loading