[IMP] web, web_editor: knowledge file command overhaul preparations

- Allow providing a custom `MediaDialog` class through `openMediaDialog` to
  allow Knowledge custom behaviors.
- Export the rendering part of `save` for the `MediaDialog` so it can be
  overridden.

task-3172056

Part-of: odoo/odoo#127021
This commit is contained in:
abd-msyukyu-odoo
2023-10-13 07:33:52 +00:00
parent 62ca95f0fd
commit 3046f7ab9d
2 changed files with 88 additions and 76 deletions
@@ -132,6 +132,91 @@ export class MediaDialog extends Component {
}
}
/**
* Render the selected media for insertion in the editor
*
* @param {Array<Object>} selectedMedia
* @returns {Array<HTMLElement>}
*/
async renderMedia(selectedMedia) {
const elements = await TABS[this.state.activeTab].Component.createElements(selectedMedia, { rpc: this.rpc, orm: this.orm });
elements.forEach(element => {
if (this.props.media) {
element.classList.add(...this.props.media.classList);
const style = this.props.media.getAttribute('style');
if (style) {
element.setAttribute('style', style);
}
if (this.state.activeTab === TABS.IMAGES.id) {
if (this.props.media.dataset.shape) {
element.dataset.shape = this.props.media.dataset.shape;
}
if (this.props.media.dataset.shapeColors) {
element.dataset.shapeColors = this.props.media.dataset.shapeColors;
}
if (this.props.media.dataset.shapeFlip) {
element.dataset.shapeFlip = this.props.media.dataset.shapeFlip;
}
if (this.props.media.dataset.shapeRotate) {
element.dataset.shapeRotate = this.props.media.dataset.shapeRotate;
}
if (this.props.media.dataset.hoverEffect) {
element.dataset.hoverEffect = this.props.media.dataset.hoverEffect;
}
if (this.props.media.dataset.hoverEffectColor) {
element.dataset.hoverEffectColor = this.props.media.dataset.hoverEffectColor;
}
if (this.props.media.dataset.hoverEffectStrokeWidth) {
element.dataset.hoverEffectStrokeWidth = this.props.media.dataset.hoverEffectStrokeWidth;
}
if (this.props.media.dataset.hoverEffectIntensity) {
element.dataset.hoverEffectIntensity = this.props.media.dataset.hoverEffectIntensity;
}
}
}
for (const otherTab of Object.keys(TABS).filter(key => key !== this.state.activeTab)) {
for (const property of TABS[otherTab].Component.mediaSpecificStyles) {
element.style.removeProperty(property);
}
element.classList.remove(...TABS[otherTab].Component.mediaSpecificClasses);
const extraClassesToRemove = [];
for (const name of TABS[otherTab].Component.mediaExtraClasses) {
if (typeof(name) === 'string') {
extraClassesToRemove.push(name);
} else { // Regex
for (const className of element.classList) {
if (className.match(name)) {
extraClassesToRemove.push(className);
}
}
}
}
// Remove classes that do not also exist in the target type.
element.classList.remove(...extraClassesToRemove.filter(candidateName => {
for (const name of TABS[this.state.activeTab].Component.mediaExtraClasses) {
if (typeof(name) === 'string') {
if (candidateName === name) {
return false;
}
} else { // Regex
for (const className of element.classList) {
if (className.match(candidateName)) {
return false;
}
}
}
}
return true;
}));
}
element.classList.remove(...this.initialIconClasses);
element.classList.remove('o_modified_image_to_save');
element.classList.remove('oe_edited_link');
element.classList.add(...TABS[this.state.activeTab].Component.mediaSpecificClasses);
});
return elements;
}
selectMedia(media, tabId, multiSelect) {
if (multiSelect) {
const isMediaSelected = this.selectedMedia[tabId].map(({ id }) => id).includes(media.id);
@@ -159,81 +244,7 @@ export class MediaDialog extends Component {
const saveSelectedMedia = selectedMedia.length
&& (this.state.activeTab !== TABS.ICONS.id || selectedMedia[0].initialIconChanged || !this.props.media);
if (saveSelectedMedia) {
const elements = await TABS[this.state.activeTab].Component.createElements(selectedMedia, { rpc: this.rpc, orm: this.orm });
elements.forEach(element => {
if (this.props.media) {
element.classList.add(...this.props.media.classList);
const style = this.props.media.getAttribute('style');
if (style) {
element.setAttribute('style', style);
}
if (this.state.activeTab === TABS.IMAGES.id) {
if (this.props.media.dataset.shape) {
element.dataset.shape = this.props.media.dataset.shape;
}
if (this.props.media.dataset.shapeColors) {
element.dataset.shapeColors = this.props.media.dataset.shapeColors;
}
if (this.props.media.dataset.shapeFlip) {
element.dataset.shapeFlip = this.props.media.dataset.shapeFlip;
}
if (this.props.media.dataset.shapeRotate) {
element.dataset.shapeRotate = this.props.media.dataset.shapeRotate;
}
if (this.props.media.dataset.hoverEffect) {
element.dataset.hoverEffect = this.props.media.dataset.hoverEffect;
}
if (this.props.media.dataset.hoverEffectColor) {
element.dataset.hoverEffectColor = this.props.media.dataset.hoverEffectColor;
}
if (this.props.media.dataset.hoverEffectStrokeWidth) {
element.dataset.hoverEffectStrokeWidth = this.props.media.dataset.hoverEffectStrokeWidth;
}
if (this.props.media.dataset.hoverEffectIntensity) {
element.dataset.hoverEffectIntensity = this.props.media.dataset.hoverEffectIntensity;
}
}
}
for (const otherTab of Object.keys(TABS).filter(key => key !== this.state.activeTab)) {
for (const property of TABS[otherTab].Component.mediaSpecificStyles) {
element.style.removeProperty(property);
}
element.classList.remove(...TABS[otherTab].Component.mediaSpecificClasses);
const extraClassesToRemove = [];
for (const name of TABS[otherTab].Component.mediaExtraClasses) {
if (typeof(name) === 'string') {
extraClassesToRemove.push(name);
} else { // Regex
for (const className of element.classList) {
if (className.match(name)) {
extraClassesToRemove.push(className);
}
}
}
}
// Remove classes that do not also exist in the target type.
element.classList.remove(...extraClassesToRemove.filter(candidateName => {
for (const name of TABS[this.state.activeTab].Component.mediaExtraClasses) {
if (typeof(name) === 'string') {
if (candidateName === name) {
return false;
}
} else { // Regex
for (const className of element.classList) {
if (className.match(candidateName)) {
return false;
}
}
}
}
return true;
}));
}
element.classList.remove(...this.initialIconClasses);
element.classList.remove('o_modified_image_to_save');
element.classList.remove('oe_edited_link');
element.classList.add(...TABS[this.state.activeTab].Component.mediaSpecificClasses);
});
const elements = await this.renderMedia(selectedMedia);
if (this.props.multiImages) {
this.props.save(elements);
} else {
@@ -1496,6 +1496,7 @@ export class Wysiwyg extends Component {
* @param {object} params
* @param {Node} [params.node] Optionnal
* @param {Node} [params.htmlClass] Optionnal
* @param {Class} [params.MediaDialog] Optional
*/
openMediaDialog(params = {}) {
const sel = this.odooEditor.document.getSelection();
@@ -1512,7 +1513,7 @@ export class Wysiwyg extends Component {
const editable = OdooEditorLib.closestElement(params.node || range.startContainer, '.o_editable') || this.odooEditor.editable;
const { resModel, resId, field, type } = this._getRecordInfo(editable);
this.env.services.dialog.add(MediaDialog, {
this.env.services.dialog.add(params.MediaDialog || MediaDialog, {
resModel,
resId,
useMediaLibrary: !!(field && (resModel === 'ir.ui.view' && field === 'arch' || type === 'html')),