Skip to content

Commit

Permalink
Changes after review
Browse files Browse the repository at this point in the history
  • Loading branch information
thecalcc committed May 15, 2024
1 parent d94849b commit 591a18b
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 59 deletions.
55 changes: 36 additions & 19 deletions scripts/apps/vocabularies/controllers/VocabularyEditController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {VocabularyItemsViewEdit} from '../components/VocabularyItemsViewEdit';
import {defaultAllowedWorkflows} from 'apps/relations/services/RelationsService';
import {EDITOR_BLOCK_FIELD_TYPE} from 'apps/workspace/content/constants';
import {getEditor3RichTextFormattingOptions} from 'apps/workspace/content/components/get-content-profiles-form-config';
import {ContentState, convertToRaw} from 'draft-js';
import {getObjectEntriesGeneric} from '../../../core/helpers/utils';

VocabularyEditController.$inject = [
'$scope',
Expand All @@ -23,7 +25,6 @@ VocabularyEditController.$inject = [
];

interface IScope extends IScopeConfigController {
item?: Partial<IArticle>;
setFormDirty: () => void;
newItemTemplate: any;
idRegex: string;
Expand All @@ -35,8 +36,13 @@ interface IScope extends IScopeConfigController {
_errorUniqueness: boolean;
errorMessage: string;
save: () => void;

// custom-editor-block props START
formattingOptionsOnChange?: (options: Array<RICH_FORMATTING_OPTION>) => void;
editorBlockFormattingOptions?: Array<{value: [RICH_FORMATTING_OPTION, string]}>;
fakeItem?: Partial<IArticle>;
// custom-editor-block props END

updateUI: () => void;
requestEditor3DirectivesToGenerateHtml: Array<() => void>;
handleTemplateValueChange: (value: string) => void;
Expand All @@ -57,6 +63,8 @@ interface IScope extends IScopeConfigController {
const idRegex = '^[a-zA-Z0-9-_]+$';
const editorBlockFieldId = 'editor_block_field';

type IFormattingOptionTuple = [notTranslatedOption: RICH_FORMATTING_OPTION, translatedOption: string];

export function VocabularyEditController(
$scope: IScope, notify, api, metadata, cvSchema, relationsService, $timeout,
) {
Expand Down Expand Up @@ -99,8 +107,7 @@ export function VocabularyEditController(
function onError(response) {
if (angular.isDefined(response.data._issues)) {
if (angular.isDefined(response.data._issues['validator exception'])) {
notify.error(gettext('Error: ' +
response.data._issues['validator exception']));
notify.error(gettext('Error: {{ message }}', {message: response.data._issues['validator exception']}));
} else if (angular.isDefined(response.data._issues.error) &&
response.data._issues.error.required_field) {
let params = response.data._issues.params;
Expand Down Expand Up @@ -129,13 +136,17 @@ export function VocabularyEditController(
if ($scope.vocabulary.field_type === EDITOR_BLOCK_FIELD_TYPE) {
const vocabulary = $scope.vocabulary;

$scope.item = {
$scope.fakeItem = {
fields_meta: {

/**
* Fake field, needed for compatibility with sdEditor3 directive
*/
[editorBlockFieldId]: {draftjsState: vocabulary.field_options?.template},
[editorBlockFieldId]: {
draftjsState: vocabulary.field_options?.template != null
? vocabulary.field_options.template
: [convertToRaw(ContentState.createFromText(''))],
},
},
};

Expand All @@ -149,21 +160,25 @@ export function VocabularyEditController(
'media',
]);

const formattingOptions = Object.entries(getEditor3RichTextFormattingOptions())
.map(([notTranslatedOption, translatedOption]) => ({value: [notTranslatedOption, translatedOption]}))
.filter(({value}: {value: [RICH_FORMATTING_OPTION, string]}) =>
excludedOptions.has(value[0]) === false,
const formattingOptions = getObjectEntriesGeneric<RICH_FORMATTING_OPTION, string>(
getEditor3RichTextFormattingOptions(),
)
.filter(([notTranslatedOption]) =>
excludedOptions.has(notTranslatedOption) === false,
)
.map(([notTranslatedOption, translatedOption]) =>
({value: [notTranslatedOption, translatedOption]}),
);

return formattingOptions as Array<{value: [RICH_FORMATTING_OPTION, string]}>;
return formattingOptions as Array<{value: IFormattingOptionTuple}>;
})();

$scope.formattingOptionsOnChange = function(options) {
vocabulary.field_options = {
formatting_options: options,
};
if (vocabulary.field_options == null) {
vocabulary.field_options = {};
}

$scope.updateUI();
vocabulary.field_options.formatting_options = options;

/**
* Apply current changes to item and save them to the field as html,
Expand All @@ -173,10 +188,7 @@ export function VocabularyEditController(
fn();
});

$scope.$broadcast('formattingOptions-update', {
editorFormat: options,
editorState: $scope.item.fields_meta[editorBlockFieldId].draftjsState,
});
$scope.updateUI();
};
}

Expand All @@ -194,9 +206,14 @@ export function VocabularyEditController(
fn();
});
$scope.vocabulary.field_options = $scope.vocabulary.field_options ?? {};

/**
* Formatting options are updated in formattingOptionsOnChange and
* don't need to be updated explicitly here again.
*/
$scope.vocabulary.field_options = {
...$scope.vocabulary.field_options,
template: $scope.item.fields_meta?.[editorBlockFieldId].draftjsState,
template: $scope.fakeItem.fields_meta?.[editorBlockFieldId].draftjsState,
};
}

Expand Down
8 changes: 3 additions & 5 deletions scripts/apps/vocabularies/views/vocabulary-config-modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,8 @@ <h3 class="modal__heading" ng-show="!vocabulary._id"><span translate>Create</spa
<label class="sd-line-input__label" translate>Formatting Options</label>
<sd-formatting-options-tree-select
value="vocabulary.field_options.formatting_options"
fields="{body_html: {}}"
field-id="'body_html'"
on-change="formattingOptionsOnChange"
formatting-options="editorBlockFormattingOptions"
options="editorBlockFormattingOptions"
/>
</div>
<div
Expand All @@ -191,9 +189,9 @@ <h3 class="modal__heading" ng-show="!vocabulary._id"><span translate>Create</spa
data-language="'en'"
data-on-change="updateUI()"
data-read-only="false"
editor-state="item.fields_meta['editor_block_field'].draftjsState"
editor-state="fakeItem.fields_meta['editor_block_field'].draftjsState"
output-editor-state="true"
data-item="item"
data-item="fakeItem"
data-refresh-trigger="refreshTrigger"
data-test-id="field--editor-block"
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import React from 'react';
import {TreeSelect} from 'superdesk-ui-framework/react';
import {IArticleField, RICH_FORMATTING_OPTION} from 'superdesk-api';
import {RICH_FORMATTING_OPTION} from 'superdesk-api';
import {gettext} from 'core/utils';

interface IProps {
value: Array<string> | null;
fieldId: string;
fields: Dictionary<string, IArticleField>;
onChange(value: Array<string>, fieldId: string): void;
formattingOptions: Array<{value: [RICH_FORMATTING_OPTION, string]}>;
onChange(value: Array<string>): void;
options: Array<{value: [RICH_FORMATTING_OPTION, string]}>;
}

export class FormattingOptionsTreeSelect extends React.Component<IProps> {
render(): React.ReactNode {
const values = this.props.value != null
? this.props.formattingOptions
? this.props.options
.filter((option) => this.props.value.includes(option.value[0]))
.map((option) => option.value)
: [];
Expand All @@ -24,9 +22,9 @@ export class FormattingOptionsTreeSelect extends React.Component<IProps> {
kind="synchronous"
getId={(option) => option[0]}
getLabel={(option) => option[1]}
getOptions={() => this.props.formattingOptions}
getOptions={() => this.props.options}
onChange={(newFormattingOptions) => {
this.props.onChange(newFormattingOptions.map((option) => option[0]), this.props.fieldId);
this.props.onChange(newFormattingOptions.map((option) => option[0]));
}}
value={values}
allowMultiple
Expand Down
2 changes: 1 addition & 1 deletion scripts/core/editor3/actions/editor3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ export function autocomplete(value: string) {
}

export type IActionPayloadSetExternalOptions =
Pick<IEditorStore, 'readOnly' | 'singleLine' | 'editorFormat' | 'spellchecking' | 'limitConfig' | 'item'>;
Partial<Pick<IEditorStore, 'readOnly' | 'singleLine' | 'editorFormat' | 'spellchecking' | 'limitConfig' | 'item'>>;

export function setExternalOptions(payload: IActionPayloadSetExternalOptions) {
return {
Expand Down
30 changes: 5 additions & 25 deletions scripts/core/editor3/directive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import createEditorStore, {
} from './store';
import {getContentStateFromHtml} from './html/from-html';

import {changeEditorState, setReadOnly, changeLimitConfig} from './actions';
import {changeEditorState, setReadOnly, changeLimitConfig, setExternalOptions} from './actions';

import ng from 'core/services/ng';
import {IArticle, RICH_FORMATTING_OPTION} from 'superdesk-api';
Expand Down Expand Up @@ -196,13 +196,6 @@ class Editor3Directive {
*/
value: '=',


/**
* @type {String}
* @description EditorValue is editorState instead of HTML.
*/
outputEditorState: '=',

/**
* @type {String}
* @description required for editor3 to be able to set metadata for fields. Mainly editor_state
Expand Down Expand Up @@ -349,12 +342,10 @@ class Editor3Directive {
}
})();

const renderEditor3 = (options?: {unmount: boolean}) => {
const renderEditor3 = () => {
const element = $element.get(0);

if (options?.unmount) {
ReactDOM.unmountComponentAtNode(element);
}
ReactDOM.unmountComponentAtNode(element);

const textStatistics = (
<Spacer h gap="8" alignItems="center" noWrap noGrow>
Expand Down Expand Up @@ -389,7 +380,6 @@ class Editor3Directive {

const editor3 = (
<Editor3
uiTheme={{}}
scrollContainer={this.scrollContainer}
singleLine={this.singleLine}
cleanPastedHtml={this.cleanPastedHtml}
Expand Down Expand Up @@ -529,18 +519,8 @@ class Editor3Directive {
renderEditor3();
});

$scope.$on('formattingOptions-update', (_e, data) => {
store = createEditorStore(
{
...this,
editorFormat: data.editorFormat,
editorState: data.editorState,
},
ng.get('spellcheck'),
true,
);

renderEditor3({unmount: false});
$scope.$watch('vm.editorFormat', (editorFormat) => {
store.dispatch(setExternalOptions({editorFormat: editorFormat}));
});

// this is triggered from MacrosController.call
Expand Down
4 changes: 4 additions & 0 deletions scripts/core/helpers/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export function pick<T extends IOnlyStringKeys, K extends keyof T>(obj: T, ...ke
return picked;
}

export function getObjectEntriesGeneric<KEY extends string, VALUE>(obj: any): Array<[KEY, VALUE]> {
return Object.entries(obj) as Array<[KEY, VALUE]>;
}

// type-safe alternative to lodash.omit
export function omit<T extends IOnlyStringKeys, K extends keyof T>(obj: T, ...keysToOmit: Array<K>): Omit<T, K> {
const keys = new Set<string>();
Expand Down
2 changes: 1 addition & 1 deletion scripts/core/ui/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,7 @@ export default angular.module('superdesk.core.ui', [
'sdFormattingOptionsTreeSelect',
reactToAngular1(
FormattingOptionsTreeSelect,
['value', 'fieldId', 'fields', 'onChange', 'formattingOptions'],
['value', 'onChange', 'options'],
),
)

Expand Down

0 comments on commit 591a18b

Please sign in to comment.