From df3c1d5407899c337aca9703128dc0676bd321d9 Mon Sep 17 00:00:00 2001 From: zhangpingchuan <228939628@qq.com> Date: Fri, 22 Dec 2023 17:56:26 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=20=E6=96=B0=E5=A2=9E=E5=AF=8C?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E7=BC=96=E8=BE=91=E5=99=A8=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=80=81=E5=92=8C=E5=8F=AA=E8=AF=BB=E6=80=81=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E3=80=81=E5=85=A8=E5=B1=8F=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E5=9D=87=E7=94=B1=E7=BC=96=E8=BE=91=E5=99=A8=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/editor/html/wang-editor/wang-editor.scss | 100 +++++++ src/editor/html/wang-editor/wang-editor.tsx | 269 +++++++++++++++++-- 2 files changed, 341 insertions(+), 28 deletions(-) diff --git a/src/editor/html/wang-editor/wang-editor.scss b/src/editor/html/wang-editor/wang-editor.scss index e7e379b5..8b658b3e 100644 --- a/src/editor/html/wang-editor/wang-editor.scss +++ b/src/editor/html/wang-editor/wang-editor.scss @@ -48,4 +48,104 @@ $html: ( z-index: 9999; } } +@include b('html-editor-readonly') { + @include b('html-toolbar') { + display: none; + } + @include b('html-editor') { + border: none; + } +} +@include b('html-footer') { + display: flex; + justify-content: end; + align-items: center; + margin-top: 12px; + gap: 16px; + margin-right: 8px; + @include e('cancel') { + height: 36px; + line-height: 36px; + color: #{getCssVar(color, text, 1)}; + opacity: 0.7; + cursor: pointer; + &:hover { + color: #{getCssVar(color, primary)}; + opacity: 1; + } + } + @include e('save') { + background-color: #{getCssVar(color, primary)}; + color: #{getCssVar(color, primary, active, text)}; + width: 96px; + height: 36px; + text-align: center; + line-height: 36px; + border-radius: 5px; + cursor: pointer; + &:hover { + box-shadow: 0px 2px 5px 1px #{getCssVar(color, primary)}; + } + } +} +@include b('html-custom-toolbar') { + display: flex; + justify-content: end; + width: 100%; + gap: 20px; + padding-right: 16px; + height: 32px; + font-size: 16px; + align-items: center; + i { + cursor: pointer; + &:hover { + color: #{getCssVar(color, primary)}; + } + } +} +@include b('html-message') { + width: 500px; + max-width: unset; + @include e('message-content') { + @include m('message-tip') { + color: #{getCssVar(color, text, 3)}; + } + } + @include e('message-cancel') { + color: #{getCssVar(color, text, 1)}; + background-color: transparent; + &:hover { + color: #{getCssVar(color, primary)}; + background-color: transparent; + } + } + @include e('message-comfire') { + background-color: #{getCssVar(color, danger)} !important; + &:hover { + box-shadow: 0px 2px 5px 1px #{getCssVar(color, danger)}; + } + } +} +@include b('html-dialog-full-screen') { + height: 80%; + @include b('html') { + padding: 0 32px; + --w-e-toolbar-bg-color: #{getCssVar(color, bg, 0)}; + } + @include b('html-custom-toolbar') { + height: 56px; + } + @include b('html-content') { + height: calc(100% - 124px); + @include b('html-editor') { + height: 100% !important; + } + } +} +@include b('html-footer-dialog') { + height: 68px; + margin-top: 0; +} + diff --git a/src/editor/html/wang-editor/wang-editor.tsx b/src/editor/html/wang-editor/wang-editor.tsx index 777a3c11..0f364afb 100644 --- a/src/editor/html/wang-editor/wang-editor.tsx +++ b/src/editor/html/wang-editor/wang-editor.tsx @@ -6,6 +6,7 @@ import { watch, Ref, defineComponent, + nextTick, } from 'vue'; import { Editor, Toolbar } from '@wangeditor/editor-for-vue'; import { IEditorConfig, IToolbarConfig } from '@wangeditor/editor'; @@ -20,6 +21,7 @@ import { import { CoreConst } from '@ibiz-template/core'; import { HtmlEditorController } from '../html-editor.controller'; import './wang-editor.scss'; +import { ElMessageBox } from 'element-plus'; type InsertFnType = (_url: string, _alt: string, _href: string) => void; @@ -64,6 +66,38 @@ const IBizHtml = defineComponent({ // 下载文件路径 const downloadUrl: Ref = ref(''); + // 允许编辑 + const enableEdit = ref(true); + + // 是否存在编辑器参数enableEdit + const hasEnableEdit = ref(false); + + // 只读状态 + const readonlyState = ref(false); + + //允许全屏打开 + const enableFullScreen = ref(false); + + // 是否全屏 + const isFullScreen = ref(false); + + const editorModel = c.model; + if (editorModel.editorParams) { + if (editorModel.editorParams.enableEdit) { + hasEnableEdit.value = true; + readonlyState.value = true; + enableEdit.value = + c.toBoolean(editorModel.editorParams.enableEdit) && + !props.readonly && + !props.disabled; + } + if (editorModel.editorParams.enableFullScreen) { + enableFullScreen.value = c.toBoolean( + editorModel.editorParams.enableFullScreen, + ); + } + } + // data响应式变更基础路径 watch( () => props.data, @@ -112,7 +146,7 @@ const IBizHtml = defineComponent({ // 编辑器配置 const editorConfig: Partial = { placeholder: c.placeHolder, - readOnly: props.readonly, + readOnly: hasEnableEdit.value ? readonlyState.value : props.readonly, MENU_CONF: { // 图片上传 uploadImage: { @@ -222,7 +256,9 @@ const IBizHtml = defineComponent({ ) { return; } - emit('change', emitValue); + if (!hasEnableEdit.value) { + emit('change', emitValue); + } }; // 编辑器销毁时的回调函数。调用 editor.destroy() 即可销毁编辑器 const handleDestroyed = (_editor: IDomEditor) => { @@ -338,6 +374,175 @@ const IBizHtml = defineComponent({ } }; + // 更改编辑状态 + const changeEditState = () => { + readonlyState.value = !readonlyState.value; + if (!readonlyState.value) { + enable(); + editorRef.value.focus(); + moveToLastStr(); + } else { + disable(); + } + }; + + // 光标移动到第一行末尾 + const moveToLastStr = () => { + if (props.value) { + const index = props.value.indexOf('

'); + if (index >= 0) { + const offset = editorRef.value.selection.anchor?.offset; + const path = editorRef.value.selection.anchor?.path; + if (offset === 0 && path.length > 0 && path[0] === 0) { + editorRef.value.move(index - 3); + } + } + } + }; + + // 绘制取消消息盒子 + const renderCancelMessage = () => { + return ( +
+

确定要取消编辑吗?

+

+ 取消编辑将无法保存修改的内容,且不能找回。 +

+
+ ); + }; + + // 取消编辑 + const cancelEdit = () => { + if (props.value !== valueHtml.value) { + ElMessageBox({ + title: '确认取消', + type: 'warning', + customClass: ns.b('message'), + message: renderCancelMessage(), + showCancelButton: true, + cancelButtonClass: ns.be('message', 'message-cancel'), + confirmButtonClass: ns.be('message', 'message-comfire'), + }) + .then(() => { + valueHtml.value = props.value || ''; + changeEditState(); + }) + .catch(() => { + // 重新聚焦 + editorRef.value.focus(); + }); + } else { + changeEditState(); + } + }; + + // 确认保存 + const save = () => { + readonlyState.value = true; + editorRef.value.disable(); + emit('change', valueHtml.value); + if (isFullScreen.value) { + isFullScreen.value = false; + } + }; + + // 绘制底部取消确认按钮 + const renderFooter = () => { + if (hasEnableEdit.value) { + return ( +
+
cancelEdit()}> + 取消 +
+
save()}> + 保存 +
+
+ ); + } + return null; + }; + + // 更新全屏状态 + const changeFullScreenState = () => { + isFullScreen.value = !isFullScreen.value; + nextTick(() => { + if (readonlyState.value) { + disable(); + } else { + enable(); + editorRef.value.focus(); + } + }); + }; + + // 绘制头部工具栏 + const renderHeaserToolbar = () => { + if (hasEnableEdit.value || enableFullScreen.value) { + return ( +
+ {hasEnableEdit.value && enableEdit.value && readonlyState.value ? ( + + ) : null} + {enableFullScreen.value ? ( + isFullScreen.value ? ( + + ) : ( + + ) + ) : null} +
+ ); + } + return null; + }; + + // 绘制编辑器内容 + const renderEditorContent = () => { + return ( +
+ + +
+ ); + }; + onMounted(() => { calcHtmlStyle(); }); @@ -360,41 +565,49 @@ const IBizHtml = defineComponent({ printHtml, disable, enable, + renderHeaserToolbar, + renderEditorContent, + renderFooter, htmlContent, + hasEnableEdit, cssVars, toolbarRef, + isFullScreen, + readonlyState, }; }, render() { - return ( -
+ return !this.isFullScreen ? ( +
+ {this.renderHeaserToolbar()} + {this.renderEditorContent()} + {this.hasEnableEdit && !this.readonlyState ? this.renderFooter() : null} +
+ ) : ( +
- - + {this.renderHeaserToolbar()} + {this.renderEditorContent()} + {this.hasEnableEdit && !this.readonlyState + ? this.renderFooter() + : null}
-
+ ); }, }); -- Gitee From 97dd6de2919853cd2fe8e21d0eca0a113701623e Mon Sep 17 00:00:00 2001 From: zhangpingchuan <228939628@qq.com> Date: Fri, 22 Dec 2023 17:56:56 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=20=E6=96=B0=E5=A2=9E=E6=BB=91?= =?UTF-8?q?=E5=8A=A8=E8=BE=93=E5=85=A5=E6=9D=A1=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E6=98=BE=E7=A4=BA=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=9D=87=E7=94=B1=E7=BC=96=E8=BE=91=E5=99=A8=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../slider/ibiz-slider/ibiz-slider.scss | 16 ++++++++++ src/editor/slider/ibiz-slider/ibiz-slider.tsx | 32 +++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/editor/slider/ibiz-slider/ibiz-slider.scss diff --git a/src/editor/slider/ibiz-slider/ibiz-slider.scss b/src/editor/slider/ibiz-slider/ibiz-slider.scss new file mode 100644 index 00000000..03f20dac --- /dev/null +++ b/src/editor/slider/ibiz-slider/ibiz-slider.scss @@ -0,0 +1,16 @@ +@include b('slider') { + width: 100%; + display: flex; + align-items: center; + @include e(text) { + .el-slider__button-wrapper { + display: none; + } + .el-slider__runway.is-disabled .el-slider__bar { + background-color: getCssVar(color, primary); + } + @include m(val) { + margin-left: getCssVar(spacing, tight); + } + } +} diff --git a/src/editor/slider/ibiz-slider/ibiz-slider.tsx b/src/editor/slider/ibiz-slider/ibiz-slider.tsx index 6f9e8b9b..30991bec 100644 --- a/src/editor/slider/ibiz-slider/ibiz-slider.tsx +++ b/src/editor/slider/ibiz-slider/ibiz-slider.tsx @@ -1,4 +1,4 @@ -import { defineComponent, ref, watch } from 'vue'; +import { computed, defineComponent, ref, watch } from 'vue'; import { getEditorEmits, getSliderProps, @@ -7,6 +7,7 @@ import { } from '@ibiz-template/vue3-util'; import { toNumber } from 'lodash-es'; import { SliderEditorController } from '../slider-editor.controller'; +import './ibiz-slider.scss'; export const IBizSlider = defineComponent({ name: 'IBizSlider', @@ -29,6 +30,10 @@ export const IBizSlider = defineComponent({ let range = false; // 是否显示输入框,仅在非范围选择时有效 let showInput = false; + // 是否显示百分比 + let showText = false; + // 格式化 + let format = '0%'; if (editorModel.editorParams) { if (editorModel.editorParams.stepvalue) { step = toNumber(editorModel.editorParams.stepvalue); @@ -48,6 +53,12 @@ export const IBizSlider = defineComponent({ if (editorModel.editorParams.showinput) { showInput = c.toBoolean(editorModel.editorParams.showinput); } + if (editorModel.editorParams.showText) { + showText = c.toBoolean(editorModel.editorParams.showText); + } + if (editorModel.editorParams.format) { + format = editorModel.editorParams.format; + } } // 当前值 @@ -77,6 +88,14 @@ export const IBizSlider = defineComponent({ { immediate: true }, ); + // 计算文本显示值 + const textVal = computed(() => { + const tempCurVal = Number(currentVal.value); + const value = Number(tempCurVal / max); + const formatValue = ibiz.util.text.format(`${value}`, format); + return formatValue; + }); + const handleChange = (currentValue: number | undefined | Array) => { if (Array.isArray(currentValue)) { emit('change', JSON.stringify(currentValue)); @@ -102,12 +121,18 @@ export const IBizSlider = defineComponent({ range, showInput, editorRef, + showText, + textVal, }; }, render() { return (
+ {this.showText ? ( + {this.textVal} + ) : null}
); }, -- Gitee From 4ac87e032ad90492ef40a94a6a38966f1b60d598 Mon Sep 17 00:00:00 2001 From: zhangpingchuan <228939628@qq.com> Date: Fri, 22 Dec 2023 17:57:27 +0800 Subject: [PATCH 3/4] =?UTF-8?q?update:=20=20=E6=9B=B4=E6=96=B0=E7=9C=8B?= =?UTF-8?q?=E6=9D=BF=E9=83=A8=E4=BB=B6=E6=89=B9=E9=87=8F=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=A0=8F=E6=89=93=E5=BC=80=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/control/kanban/kanban.scss | 25 ++++++++++ src/control/kanban/kanban.tsx | 86 ++++++++++++++++++++++++---------- 2 files changed, 86 insertions(+), 25 deletions(-) diff --git a/src/control/kanban/kanban.scss b/src/control/kanban/kanban.scss index 9a4c485f..45a6f29e 100644 --- a/src/control/kanban/kanban.scss +++ b/src/control/kanban/kanban.scss @@ -138,10 +138,35 @@ $control-kanban: ( padding: getCssVar(spacing, tight); font-size: getCssVar(control-kanban, font-size); color: getCssVar(color, primary); + cursor: pointer; &:hover { background-color: getCssVar(color, fill, 0); } } + @include e(actions-dropdown) { + padding: getCssVar(spacing, extra, tight) 0; + .#{bem(action-toolbar)} { + @include flex(column) + } + .el-button { + --el-button-size: #{getCssVar(height-control, large)}; + margin: 0; + width: 100%; + justify-content: flex-start; + font-size: getCssVar('font-size', 'regular'); + padding: getCssVar(spacing, tight) getCssVar(spacing, base); + color: getCssVar(color, primary, text); + ion-icon { + margin-right: getCssVar(spacing, extra, tight); + } + } + .el-button.is-text:not(.is-disabled) { + &:hover { + border-color: var(--el-button-hover-border-color); + background-color: var(--el-button-hover-bg-color); + } + } + } } @include b(control-kanban-item) { diff --git a/src/control/kanban/kanban.tsx b/src/control/kanban/kanban.tsx index 5d04fc0b..61ae2297 100644 --- a/src/control/kanban/kanban.tsx +++ b/src/control/kanban/kanban.tsx @@ -53,6 +53,17 @@ export const KanbanControl = defineComponent({ return c.state.batching ? c.state.selectGroupKey : ''; }); + const quickToolbarModel = c.model.controls?.find(item => { + return ( + item.name === `${c.model.name!}_quicktoolbar` || + item.name === `${c.model.name!}_groupquicktoolbar` + ); + }); + + const batchToolbarModel = c.model.controls?.find(item => { + return item.name === `${c.model.name!}_batchtoolbar`; + }); + const groupClass = c.model.groupSysCss?.cssName || ''; // 分组样式表 const collapseMap: Ref = ref({}); @@ -167,19 +178,16 @@ export const KanbanControl = defineComponent({ const renderQuickToolBar = ( group: IKanbanGroupState, ): VNode | undefined => { - const ctrlModel = c.model.controls?.find(item => { - return ( - item.name === `${c.model.name!}_quicktoolbar` || - item.name === `${c.model.name!}_groupquicktoolbar` - ); - }); - if (!ctrlModel) { + if (!quickToolbarModel) { return; } return ( @@ -189,16 +197,16 @@ export const KanbanControl = defineComponent({ const renderBatchToolBar = ( group: IKanbanGroupState, ): VNode | undefined => { - const ctrlModel = c.model.controls?.find(item => { - return item.name === `${c.model.name!}_batchtoolbar`; - }); - if (!ctrlModel) { + if (!batchToolbarModel) { return; } return (
@@ -350,6 +358,9 @@ export const KanbanControl = defineComponent({ }; const renderGroupToolbar = (group: IKanbanGroupState) => { + const showActionBar = + (c.model.groupUIActionGroup && group.groupActionGroupState) || + batchToolbarModel; if (batchKey.value === group.key) { return ( )} - {c.model.groupUIActionGroup && group.groupActionGroupState && ( - { - c.onGroupToolbarClick(detail, event, group); + trigger='click' + > + {{ + default: (): VNode => ···, + dropdown: (): VNode => ( +
+ {c.model.groupUIActionGroup && + group.groupActionGroupState && ( + { + c.onGroupToolbarClick(detail, event, group); + }} + > + )} + {batchToolbarModel && ( + { + c.openBatch(group.key); + }} + > + + 批量操作 + + )} +
+ ), }} - >
+ )}
); -- Gitee From 573a031b0dfd4b542ca9ddf567617162958a5c3c Mon Sep 17 00:00:00 2001 From: zhangpingchuan <228939628@qq.com> Date: Fri, 22 Dec 2023 17:57:50 +0800 Subject: [PATCH 4/4] =?UTF-8?q?docs:=20=20=E6=9B=B4=E6=96=B0=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb7cf14e..d1ae2e6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ ## [Unreleased] +- 新增富文本编辑器编辑态和只读态切换功能、全屏功能,均由编辑器参数控制 +- 新增滑动输入条编辑器文本显示功能,均由编辑器参数控制 +- 更新看板部件批量操作工具栏打开方式 + ## [0.4.15] - 2023-12-20 ### Added -- Gitee