@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.
@@ -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.resourceConfig = undefined;
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
- resourceConfig?: AdminForthResource = undefined;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/rich-editor",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
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