From 58fb7af007ae8d4c7ec22479af30efa09cc8cf6c Mon Sep 17 00:00:00 2001 From: Tristan Matthias Date: Sun, 17 Feb 2019 15:59:25 +0800 Subject: [PATCH] feat(admin): optimized wysiwyg editor --- TODO.md | 1 - packages/admin/package.json | 3 +- .../src/components/ui/MediaGrid/MediaGrid.ts | 4 +- .../src/components/ui/WYSIWYG/WYSIWYG.ts | 42 +++++++++++-------- .../src/components/ui/WYSIWYG/wysiwyg-css.ts | 2 +- .../src/components/ui/WYSIWYG/wysiwyg.scss | 30 +++++++++++++ .../plugin-default-pages/static/icons.svg | 2 +- 7 files changed, 61 insertions(+), 23 deletions(-) diff --git a/TODO.md b/TODO.md index acc3d1d..c3705a1 100644 --- a/TODO.md +++ b/TODO.md @@ -12,7 +12,6 @@ | [packages/core-server/src/lib/App/App.ts](packages/core-server/src/lib/App/App.ts#L187) | 187 | convert to gzip serve | [packages/admin/src/components/pages/Login/PageLogin.ts](packages/admin/src/components/pages/Login/PageLogin.ts#L66) | 66 | Loading state for login form | [packages/admin/src/components/ui/ResourcePage/ResourcePage.ts](packages/admin/src/components/ui/ResourcePage/ResourcePage.ts#L129) | 129 | Repair list columns on ResourceTable -| [packages/admin/src/components/ui/WYSIWYG/WYSIWYG.ts](packages/admin/src/components/ui/WYSIWYG/WYSIWYG.ts#L102) | 102 | Make more efficient | [packages/plugin-core-api/src/v1/controllers/themes/installed.ts](packages/plugin-core-api/src/v1/controllers/themes/installed.ts#L11) | 11 | Move to db call | [packages/core-server/src/middleware/format/lib/__tests__/Formatter.test.ts](packages/core-server/src/middleware/format/lib/__tests__/Formatter.test.ts#L242) | 242 | core-server.Formatter.sendHTML | [packages/core-server/src/middleware/format/lib/__tests__/Formatter.test.ts](packages/core-server/src/middleware/format/lib/__tests__/Formatter.test.ts#L245) | 245 | core-server.Formatter.sendText diff --git a/packages/admin/package.json b/packages/admin/package.json index b802c63..f997bf1 100644 --- a/packages/admin/package.json +++ b/packages/admin/package.json @@ -11,8 +11,7 @@ "build:ts": "tsc -p .", "build:rollup": "rollup -c", "build:sass": "sass-render src/components/**/*.scss --suffix=-css.ts -i '../../node_modules,../../' --template ./style-template.ts", - "build": "yarn clean; yarn build:sass; yarn build:ts; yarn build:rollup;", - "build:prod": "yarn clean; yarn build:sass; yarn build:ts; NODE_ENV=production yarn build:rollup; yarn gzip", + "build": "yarn clean; yarn build:sass; yarn build:ts; NODE_ENV=production yarn build:rollup; yarn gzip", "watch:ts": "yarn build:ts -w", "watch:rollup": "yarn build:rollup -w", "watch:sass": "yarn build:sass -w", diff --git a/packages/admin/src/components/ui/MediaGrid/MediaGrid.ts b/packages/admin/src/components/ui/MediaGrid/MediaGrid.ts index 90ff784..22e71d4 100644 --- a/packages/admin/src/components/ui/MediaGrid/MediaGrid.ts +++ b/packages/admin/src/components/ui/MediaGrid/MediaGrid.ts @@ -52,14 +52,16 @@ export class MediaGrid extends connect(store)(LitElement) { return this._value; } + @property() // tslint:disable-next-line:variable-name private __value: MediaResource[] = []; - @property() private set _value(v) { this.__value = v; this.dispatchEvent(new CustomEvent(EVENT_CHANGED, { detail: this.__value })); + // tslint:disable-next-line no-floating-promises + this.requestUpdate(); } private get _value() { return this.__value; diff --git a/packages/admin/src/components/ui/WYSIWYG/WYSIWYG.ts b/packages/admin/src/components/ui/WYSIWYG/WYSIWYG.ts index dc8a172..50fbe8d 100644 --- a/packages/admin/src/components/ui/WYSIWYG/WYSIWYG.ts +++ b/packages/admin/src/components/ui/WYSIWYG/WYSIWYG.ts @@ -1,6 +1,7 @@ // @ts-ignore import gjs from 'grapesjs'; import { customElement, html, LitElement, property, svg } from 'lit-element'; +import { MediaResource } from 'src/store/state'; import CSS from './wysiwyg-css'; @customElement('ui-wysiwyg') @@ -10,14 +11,17 @@ export class WYSIWYG extends LitElement { // GJS Editor private _editor: any; private _initialValue: string = ''; + private _lastMediaSelected: MediaResource | null = null; get _modalContainer() { return document.querySelector('ui-modal-container')!; } - public async selectMedia() { + public async selectMedia(): Promise { this._modalContainer.open('modal-media-selector'); - return this._modalContainer.waitFor(); + const r = await this._modalContainer.waitFor<{ resources: MediaResource[] }>(); + if (r) return this._lastMediaSelected = r.resources[0]; + else return false; } @@ -26,10 +30,11 @@ export class WYSIWYG extends LitElement { return this._editor.getHtml(); } set value(v: string) { - if (!this._editor) { - this._initialValue = v; - return; - } else this._editor.setComponents(v); + this._initialValue = v; + // if (!this._editor) { + // this._initialValue = v; + // return; + // } else this._editor.setComponents(v); } public render() { @@ -85,22 +90,25 @@ export class WYSIWYG extends LitElement { const self = this; - this._editor.Commands.add('open-assets', { - async run(editor: any, sender: any) { - const media = await self.selectMedia(); - if (media) { - // @ts-ignore - const src = `/api/v1/media/${media.resources[0].id}`; - - self._editor.getSelected().setAttributes({src}); - } + this._editor.Commands.add('open-assets', { + async run(editor: any, sender: any, opts = {}) { + await self._setImageSrc(opts.target); } }); - this._editor.on('change', () => { - // TODO: Make more efficient + this._editor.on('change:changesCount', () => { this.dispatchEvent(new CustomEvent('change')); }); } + + private async _setImageSrc(model: any) { + const media = await this.selectMedia(); + if (media) { + const src = `/api/v1/media/${media.id}`; + + const img = this._editor.getSelected(); + img.set('src', src); + } + } } diff --git a/packages/admin/src/components/ui/WYSIWYG/wysiwyg-css.ts b/packages/admin/src/components/ui/WYSIWYG/wysiwyg-css.ts index 67c4d5b..e3eedcb 100644 --- a/packages/admin/src/components/ui/WYSIWYG/wysiwyg-css.ts +++ b/packages/admin/src/components/ui/WYSIWYG/wysiwyg-css.ts @@ -1,4 +1,4 @@ import {css} from 'lit-element'; // tslint:disable-next-line no-default-export export-name -export default css`:host .gjs-rte-actionbar .gjs-rte-action{width:var(--size-main);height:var(--size-main)}:host{display:block;border:var(--input-border);border-radius:var(--border-radius);overflow:hidden}:host #gjs{padding:var(--size-small);background:var(--color-white)}:host .gjs-cv-canvas{top:0;width:100%;height:100%}:host .gjs-block-label{font-size:1.5rem}:host .gjs-one-bg{background:var(--color-grey-100)}:host .gjs-block{padding:0 var(--size-tiny);height:var(--size-medium);line-height:var(--size-medium);width:auto;min-height:auto;margin:1rem;margin-right:0;border-radius:var(--border-radius)}:host .gjs-block .gjs-block-label{height:100%;line-height:var(--size-medium);color:var(--color-main);font-family:var(--font-family)}:host .gjs-rte-toolbar{border-radius:var(--border-radius);border:1px solid var(--color-grey-200);overflow:hidden}:host .gjs-rte-actionbar{font-size:1.5rem}:host .gjs-rte-actionbar .gjs-rte-action{background:var(--color-white);border-right:1px solid var(--color-grey-100);color:var(--color-main)}:host .gjs-rte-actionbar .gjs-rte-active{background:var(--color-main);color:var(--color-white)} +export default css`:host .gjs-rte-actionbar .gjs-rte-action{width:var(--size-main);height:var(--size-main)}:host{display:block;border:var(--input-border);border-radius:var(--border-radius);overflow:hidden}:host #gjs{padding:var(--size-small);background:var(--color-white)}:host .gjs-cv-canvas{top:0;width:100%;height:100%}:host .gjs-block-label{font-size:1.5rem}:host .gjs-one-bg{background:var(--color-grey-100)}:host .gjs-block{padding:0 var(--size-tiny);height:var(--size-medium);line-height:var(--size-medium);width:auto;min-height:auto;margin:1rem;margin-right:0;border-radius:var(--border-radius)}:host .gjs-block .gjs-block-label{height:100%;line-height:var(--size-medium);color:var(--color-main);font-family:var(--font-family)}:host .gjs-rte-toolbar{border-radius:var(--border-radius);border:1px solid var(--color-grey-200);overflow:hidden}:host .gjs-rte-actionbar{font-size:1.5rem}:host .gjs-rte-actionbar .gjs-rte-action{background:var(--color-white);border-right:1px solid var(--color-grey-100);color:var(--color-main)}:host .gjs-rte-actionbar .gjs-rte-active{background:var(--color-main);color:var(--color-white)}:host .gjs-toolbar{white-space:nowrap}:host .gjs-toolbar .fa{display:inline-block;width:var(--size-medium);height:var(--size-medium);background-size:100%;filter:invert(1)}:host .gjs-toolbar .fa:before{content:''}:host .gjs-toolbar .fa.fa-arrow-up{background-image:url("/origami/icons.svg#arrow-up")}:host .gjs-toolbar .fa.fa-arrows{background-image:url("/origami/icons.svg#reorder")}:host .gjs-toolbar .fa.fa-clone{background-image:url("/origami/icons.svg#copy")}:host .gjs-toolbar .fa.fa-trash-o{background-image:url("/origami/icons.svg#remove")} `; diff --git a/packages/admin/src/components/ui/WYSIWYG/wysiwyg.scss b/packages/admin/src/components/ui/WYSIWYG/wysiwyg.scss index 3d76f6b..4aead06 100644 --- a/packages/admin/src/components/ui/WYSIWYG/wysiwyg.scss +++ b/packages/admin/src/components/ui/WYSIWYG/wysiwyg.scss @@ -63,4 +63,34 @@ color: var(--color-white); } } + + .gjs-toolbar { + white-space: nowrap; + + .fa { + display: inline-block; + width: var(--size-medium); + height: var(--size-medium); + background-size: 100%; + filter: invert(1); + + &:before { + content: ''; + } + + &.fa-arrow-up { + background-image: url('/origami/icons.svg#arrow-up'); + } + &.fa-arrows { + background-image: url('/origami/icons.svg#reorder'); + } + &.fa-clone { + background-image: url('/origami/icons.svg#copy'); + } + &.fa-trash-o { + background-image: url('/origami/icons.svg#remove'); + } + } + } } + diff --git a/packages/plugin-default-pages/static/icons.svg b/packages/plugin-default-pages/static/icons.svg index a2885bd..333fb86 100644 --- a/packages/plugin-default-pages/static/icons.svg +++ b/packages/plugin-default-pages/static/icons.svg @@ -1 +1 @@ - \ No newline at end of file +