@adminforth/rich-editor 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom/quillEditor.vue +25 -5
- package/dist/custom/quillEditor.vue +25 -5
- package/dist/index.js +26 -3
- package/index.ts +34 -4
- package/package.json +1 -1
- package/types.ts +30 -1
package/custom/quillEditor.vue
CHANGED
|
@@ -89,12 +89,13 @@ onMounted(() => {
|
|
|
89
89
|
modules: {
|
|
90
90
|
toolbar: props.meta.toolbar || [
|
|
91
91
|
['bold', 'italic', 'underline', 'strike'], // toggled buttons
|
|
92
|
-
['blockquote', 'code-block', 'link'],
|
|
92
|
+
['blockquote', 'code-block', 'link', ...props.meta.uploadPluginInstanceId ? ['image'] : []],
|
|
93
93
|
// [
|
|
94
94
|
// // 'image',
|
|
95
95
|
// // 'video',
|
|
96
96
|
// // 'formula'
|
|
97
97
|
// ],
|
|
98
|
+
|
|
98
99
|
|
|
99
100
|
[{ 'header': 2 }, { 'header': 3 }], // custom button values
|
|
100
101
|
[{ 'list': 'ordered'}, { 'list': 'bullet' }, { 'list': 'check' }],
|
|
@@ -372,7 +373,6 @@ function removeCompletionOnBlur() {
|
|
|
372
373
|
.ql-toolbar.ql-snow[class] {
|
|
373
374
|
border: none;
|
|
374
375
|
padding: 0 0 1rem 0;
|
|
375
|
-
|
|
376
376
|
.ql-picker-label{
|
|
377
377
|
padding-left: 0;
|
|
378
378
|
}
|
|
@@ -380,12 +380,10 @@ function removeCompletionOnBlur() {
|
|
|
380
380
|
|
|
381
381
|
.ql-container {
|
|
382
382
|
border: 0;
|
|
383
|
-
|
|
384
383
|
.ql-editor {
|
|
385
384
|
position: relative;
|
|
386
385
|
padding: 0;
|
|
387
386
|
min-height: 100px;
|
|
388
|
-
|
|
389
387
|
&.ql-blank::before {
|
|
390
388
|
left: 0px;
|
|
391
389
|
font-style: normal;
|
|
@@ -393,7 +391,6 @@ function removeCompletionOnBlur() {
|
|
|
393
391
|
}
|
|
394
392
|
}
|
|
395
393
|
|
|
396
|
-
|
|
397
394
|
.ql-editor:not(:focus) [completer] {
|
|
398
395
|
display: none;
|
|
399
396
|
}
|
|
@@ -403,6 +400,29 @@ function removeCompletionOnBlur() {
|
|
|
403
400
|
font-style: italic;
|
|
404
401
|
}
|
|
405
402
|
|
|
403
|
+
.ql-snow .ql-stroke {
|
|
404
|
+
@apply dark:stroke-darkPrimary;
|
|
405
|
+
@apply stroke-lightPrimary;
|
|
406
|
+
|
|
407
|
+
}
|
|
408
|
+
.ql-snow button:hover .ql-stroke,
|
|
409
|
+
.ql-snow [role="button"]:hover .ql-stroke {
|
|
410
|
+
@apply dark:stroke-darkPrimary;
|
|
411
|
+
@apply stroke-lightPrimary;
|
|
412
|
+
filter: brightness(1.3);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.ql-snow .ql-fill {
|
|
416
|
+
@apply dark:fill-darkPrimary;
|
|
417
|
+
@apply fill-lightPrimary;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.ql-snow button:hover .ql-fill {
|
|
421
|
+
@apply dark:fill-darkPrimary;
|
|
422
|
+
@apply fill-lightPrimary;
|
|
423
|
+
filter: brightness(1.3);
|
|
424
|
+
}
|
|
425
|
+
|
|
406
426
|
}
|
|
407
427
|
|
|
408
428
|
|
|
@@ -89,12 +89,13 @@ onMounted(() => {
|
|
|
89
89
|
modules: {
|
|
90
90
|
toolbar: props.meta.toolbar || [
|
|
91
91
|
['bold', 'italic', 'underline', 'strike'], // toggled buttons
|
|
92
|
-
['blockquote', 'code-block', 'link'],
|
|
92
|
+
['blockquote', 'code-block', 'link', ...props.meta.uploadPluginInstanceId ? ['image'] : []],
|
|
93
93
|
// [
|
|
94
94
|
// // 'image',
|
|
95
95
|
// // 'video',
|
|
96
96
|
// // 'formula'
|
|
97
97
|
// ],
|
|
98
|
+
|
|
98
99
|
|
|
99
100
|
[{ 'header': 2 }, { 'header': 3 }], // custom button values
|
|
100
101
|
[{ 'list': 'ordered'}, { 'list': 'bullet' }, { 'list': 'check' }],
|
|
@@ -372,7 +373,6 @@ function removeCompletionOnBlur() {
|
|
|
372
373
|
.ql-toolbar.ql-snow[class] {
|
|
373
374
|
border: none;
|
|
374
375
|
padding: 0 0 1rem 0;
|
|
375
|
-
|
|
376
376
|
.ql-picker-label{
|
|
377
377
|
padding-left: 0;
|
|
378
378
|
}
|
|
@@ -380,12 +380,10 @@ function removeCompletionOnBlur() {
|
|
|
380
380
|
|
|
381
381
|
.ql-container {
|
|
382
382
|
border: 0;
|
|
383
|
-
|
|
384
383
|
.ql-editor {
|
|
385
384
|
position: relative;
|
|
386
385
|
padding: 0;
|
|
387
386
|
min-height: 100px;
|
|
388
|
-
|
|
389
387
|
&.ql-blank::before {
|
|
390
388
|
left: 0px;
|
|
391
389
|
font-style: normal;
|
|
@@ -393,7 +391,6 @@ function removeCompletionOnBlur() {
|
|
|
393
391
|
}
|
|
394
392
|
}
|
|
395
393
|
|
|
396
|
-
|
|
397
394
|
.ql-editor:not(:focus) [completer] {
|
|
398
395
|
display: none;
|
|
399
396
|
}
|
|
@@ -403,6 +400,29 @@ function removeCompletionOnBlur() {
|
|
|
403
400
|
font-style: italic;
|
|
404
401
|
}
|
|
405
402
|
|
|
403
|
+
.ql-snow .ql-stroke {
|
|
404
|
+
@apply dark:stroke-darkPrimary;
|
|
405
|
+
@apply stroke-lightPrimary;
|
|
406
|
+
|
|
407
|
+
}
|
|
408
|
+
.ql-snow button:hover .ql-stroke,
|
|
409
|
+
.ql-snow [role="button"]:hover .ql-stroke {
|
|
410
|
+
@apply dark:stroke-darkPrimary;
|
|
411
|
+
@apply stroke-lightPrimary;
|
|
412
|
+
filter: brightness(1.3);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.ql-snow .ql-fill {
|
|
416
|
+
@apply dark:fill-darkPrimary;
|
|
417
|
+
@apply fill-lightPrimary;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.ql-snow button:hover .ql-fill {
|
|
421
|
+
@apply dark:fill-darkPrimary;
|
|
422
|
+
@apply fill-lightPrimary;
|
|
423
|
+
filter: brightness(1.3);
|
|
424
|
+
}
|
|
425
|
+
|
|
406
426
|
}
|
|
407
427
|
|
|
408
428
|
|
package/dist/index.js
CHANGED
|
@@ -8,10 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { AdminForthPlugin } from "adminforth";
|
|
11
|
+
// options:
|
|
12
|
+
// attachments: {
|
|
13
|
+
// attachmentResource: 'description_images',
|
|
14
|
+
// attachmentFieldName: 'image_path',
|
|
15
|
+
// attachmentRecordIdFieldName: 'record_id',
|
|
16
|
+
// attachmentResourceIdFieldName: 'resource_id',
|
|
17
|
+
// },
|
|
11
18
|
export default class RichEditorPlugin extends AdminForthPlugin {
|
|
12
19
|
constructor(options) {
|
|
13
20
|
super(options, import.meta.url);
|
|
14
|
-
this.
|
|
21
|
+
this.activationOrder = 100000;
|
|
15
22
|
this.options = options;
|
|
16
23
|
}
|
|
17
24
|
modifyResourceConfig(adminforth, resourceConfig) {
|
|
@@ -19,19 +26,35 @@ export default class RichEditorPlugin extends AdminForthPlugin {
|
|
|
19
26
|
modifyResourceConfig: { get: () => super.modifyResourceConfig }
|
|
20
27
|
});
|
|
21
28
|
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
-
var _a, _b;
|
|
29
|
+
var _a, _b, _c;
|
|
23
30
|
_super.modifyResourceConfig.call(this, adminforth, resourceConfig);
|
|
24
|
-
this.resourceConfig = resourceConfig;
|
|
25
31
|
const c = resourceConfig.columns.find(c => c.name === this.options.htmlFieldName);
|
|
26
32
|
if (!c) {
|
|
27
33
|
throw new Error(`Column ${this.options.htmlFieldName} not found in resource ${resourceConfig.label}`);
|
|
28
34
|
}
|
|
35
|
+
if (this.options.attachments) {
|
|
36
|
+
const resource = adminforth.config.resources.find(r => r.resourceId === this.options.attachments.attachmentResource);
|
|
37
|
+
if (!resource) {
|
|
38
|
+
throw new Error(`Resource '${this.options.attachments.attachmentResource}' not found`);
|
|
39
|
+
}
|
|
40
|
+
const field = resource.columns.find(c => c.name === this.options.attachments.attachmentFieldName);
|
|
41
|
+
if (!field) {
|
|
42
|
+
throw new Error(`Field '${this.options.attachments.attachmentFieldName}' not found in resource '${this.options.attachments.attachmentResource}'`);
|
|
43
|
+
}
|
|
44
|
+
const plugin = adminforth.activatedPlugins.find(p => p.resourceConfig.resourceId === this.options.attachments.attachmentResource &&
|
|
45
|
+
p.pluginOptions.pathColumnName === this.options.attachments.attachmentFieldName);
|
|
46
|
+
if (!plugin) {
|
|
47
|
+
throw new Error(`Plugin for attachment field '${this.options.attachments.attachmentFieldName}' not found in resource '${this.options.attachments.attachmentResource}', please check if Upload Plugin is installed on the field ${this.options.attachments.attachmentFieldName}`);
|
|
48
|
+
}
|
|
49
|
+
this.uploadPlugin = plugin;
|
|
50
|
+
}
|
|
29
51
|
const filed = {
|
|
30
52
|
file: this.componentPath('quillEditor.vue'),
|
|
31
53
|
meta: {
|
|
32
54
|
pluginInstanceId: this.pluginInstanceId,
|
|
33
55
|
debounceTime: ((_b = (_a = this.options.completion) === null || _a === void 0 ? void 0 : _a.expert) === null || _b === void 0 ? void 0 : _b.debounceTime) || 300,
|
|
34
56
|
shouldComplete: !!this.options.completion,
|
|
57
|
+
uploadPluginInstanceId: (_c = this.uploadPlugin) === null || _c === void 0 ? void 0 : _c.pluginInstanceId,
|
|
35
58
|
}
|
|
36
59
|
};
|
|
37
60
|
if (!c.components) {
|
package/index.ts
CHANGED
|
@@ -2,10 +2,19 @@
|
|
|
2
2
|
import { IAdminForth, IHttpServer, AdminForthPlugin, AdminForthResource } from "adminforth";
|
|
3
3
|
import { PluginOptions } from './types.js';
|
|
4
4
|
|
|
5
|
+
// options:
|
|
6
|
+
// attachments: {
|
|
7
|
+
// attachmentResource: 'description_images',
|
|
8
|
+
// attachmentFieldName: 'image_path',
|
|
9
|
+
// attachmentRecordIdFieldName: 'record_id',
|
|
10
|
+
// attachmentResourceIdFieldName: 'resource_id',
|
|
11
|
+
// },
|
|
5
12
|
|
|
6
13
|
export default class RichEditorPlugin extends AdminForthPlugin {
|
|
7
14
|
options: PluginOptions;
|
|
8
|
-
|
|
15
|
+
uploadPlugin: AdminForthPlugin;
|
|
16
|
+
|
|
17
|
+
activationOrder: number = 100000;
|
|
9
18
|
|
|
10
19
|
constructor(options: PluginOptions) {
|
|
11
20
|
super(options, import.meta.url);
|
|
@@ -14,27 +23,46 @@ export default class RichEditorPlugin extends AdminForthPlugin {
|
|
|
14
23
|
|
|
15
24
|
async modifyResourceConfig(adminforth: IAdminForth, resourceConfig: AdminForthResource) {
|
|
16
25
|
super.modifyResourceConfig(adminforth, resourceConfig);
|
|
17
|
-
this.resourceConfig = resourceConfig;
|
|
18
|
-
|
|
19
26
|
|
|
20
27
|
const c = resourceConfig.columns.find(c => c.name === this.options.htmlFieldName);
|
|
21
28
|
if (!c) {
|
|
22
29
|
throw new Error(`Column ${this.options.htmlFieldName} not found in resource ${resourceConfig.label}`);
|
|
23
30
|
}
|
|
31
|
+
|
|
32
|
+
if (this.options.attachments) {
|
|
33
|
+
const resource = adminforth.config.resources.find(r => r.resourceId === this.options.attachments!.attachmentResource);
|
|
34
|
+
if (!resource) {
|
|
35
|
+
throw new Error(`Resource '${this.options.attachments!.attachmentResource}' not found`);
|
|
36
|
+
}
|
|
37
|
+
const field = resource.columns.find(c => c.name === this.options.attachments!.attachmentFieldName);
|
|
38
|
+
if (!field) {
|
|
39
|
+
throw new Error(`Field '${this.options.attachments!.attachmentFieldName}' not found in resource '${this.options.attachments!.attachmentResource}'`);
|
|
40
|
+
}
|
|
41
|
+
const plugin = adminforth.activatedPlugins.find(p =>
|
|
42
|
+
p.resourceConfig!.resourceId === this.options.attachments!.attachmentResource &&
|
|
43
|
+
p.pluginOptions.pathColumnName === this.options.attachments!.attachmentFieldName);
|
|
44
|
+
if (!plugin) {
|
|
45
|
+
throw new Error(`Plugin for attachment field '${this.options.attachments!.attachmentFieldName}' not found in resource '${this.options.attachments!.attachmentResource}', please check if Upload Plugin is installed on the field ${this.options.attachments!.attachmentFieldName}`);
|
|
46
|
+
}
|
|
47
|
+
this.uploadPlugin = plugin;
|
|
48
|
+
}
|
|
49
|
+
|
|
24
50
|
const filed = {
|
|
25
51
|
file: this.componentPath('quillEditor.vue'),
|
|
26
52
|
meta: {
|
|
27
53
|
pluginInstanceId: this.pluginInstanceId,
|
|
28
54
|
debounceTime: this.options.completion?.expert?.debounceTime || 300,
|
|
29
55
|
shouldComplete: !!this.options.completion,
|
|
56
|
+
uploadPluginInstanceId: this.uploadPlugin?.pluginInstanceId,
|
|
30
57
|
}
|
|
31
58
|
}
|
|
59
|
+
|
|
32
60
|
if (!c.components) {
|
|
33
61
|
c.components = {};
|
|
34
62
|
}
|
|
35
63
|
c.components.create = filed;
|
|
36
64
|
c.components.edit = filed;
|
|
37
|
-
|
|
65
|
+
|
|
38
66
|
}
|
|
39
67
|
|
|
40
68
|
validateConfigAfterDiscover(adminforth: IAdminForth, resourceConfig: AdminForthResource) {
|
|
@@ -42,6 +70,8 @@ export default class RichEditorPlugin extends AdminForthPlugin {
|
|
|
42
70
|
if (this.options.completion && this.options.completion.provider !== 'openai-chat-gpt') {
|
|
43
71
|
throw new Error(`Invalid provider ${this.options.completion.provider}`);
|
|
44
72
|
}
|
|
73
|
+
|
|
74
|
+
|
|
45
75
|
}
|
|
46
76
|
|
|
47
77
|
instanceUniqueRepresentation(pluginOptions: any) : string {
|
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -134,6 +134,35 @@ export interface PluginOptions {
|
|
|
134
134
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Allows to attach images to the HTML text
|
|
139
|
+
* Requires to have a separate resource with Upload Plugin installed on attachment field.
|
|
140
|
+
* Each attachment used in HTML will create one record in the attachment resource.
|
|
141
|
+
*/
|
|
142
|
+
attachments?: {
|
|
143
|
+
/**
|
|
144
|
+
* Resource name where images are stored. Should point to the existing resource.
|
|
145
|
+
*/
|
|
146
|
+
attachmentResource: string;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Field name in the attachment resource where image is stored. Should point to the existing field in the attachment resource.
|
|
150
|
+
* Also there should be upload plugin installed on this field.
|
|
151
|
+
*/
|
|
152
|
+
attachmentFieldName: 'image_path',
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* When attachment is created, it will be linked to the record with this field name.
|
|
156
|
+
* For example when RichEditor installed on description field of appartment resource,
|
|
157
|
+
* field in attachment resource describet hear will store id of appartment record.
|
|
158
|
+
*/
|
|
159
|
+
attachmentRecordIdFieldName: 'record_id',
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* When attachment is created, it will be linked to the resource with this field name.
|
|
163
|
+
* For example when RichEditor installed on description field of appartment resource, it will store id of appartment resource.
|
|
164
|
+
*/
|
|
165
|
+
attachmentResourceIdFieldName: 'resource_id',
|
|
166
|
+
},
|
|
138
167
|
}
|
|
139
168
|
|