obsidian-confluence 5.6.0
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/CHANGELOG.md +1002 -0
- package/README.md +72 -0
- package/docs/screenshots/commands.png +0 -0
- package/docs/screenshots/ribbon.png +0 -0
- package/docs/screenshots/settings.png +0 -0
- package/esbuild.config.mjs +55 -0
- package/package.json +33 -0
- package/src/CompletedModal.tsx +160 -0
- package/src/ConfluencePerPageForm.tsx +525 -0
- package/src/ConfluenceSettingTab.ts +124 -0
- package/src/MyBaseClient.ts +220 -0
- package/src/adaptors/obsidian.ts +146 -0
- package/src/custom.d.ts +19 -0
- package/src/main.ts +501 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
import { Modal, App, FrontMatterCache } from "obsidian";
|
|
2
|
+
import ReactDOM from "react-dom";
|
|
3
|
+
import React, { useState, ChangeEvent } from "react";
|
|
4
|
+
import { ConfluencePageConfig } from "md-confluence-lib";
|
|
5
|
+
import { Property } from "csstype";
|
|
6
|
+
|
|
7
|
+
export type ConfluencePerPageUIValues = {
|
|
8
|
+
[K in keyof ConfluencePageConfig.ConfluencePerPageConfig]: {
|
|
9
|
+
value:
|
|
10
|
+
| ConfluencePageConfig.ConfluencePerPageConfig[K]["default"]
|
|
11
|
+
| undefined;
|
|
12
|
+
isSet: boolean;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function mapFrontmatterToConfluencePerPageUIValues(
|
|
17
|
+
frontmatter: FrontMatterCache | undefined,
|
|
18
|
+
): ConfluencePerPageUIValues {
|
|
19
|
+
const config = ConfluencePageConfig.conniePerPageConfig;
|
|
20
|
+
const result: Partial<ConfluencePerPageUIValues> = {};
|
|
21
|
+
|
|
22
|
+
if (!frontmatter) {
|
|
23
|
+
throw new Error("Missing frontmatter");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
for (const propertyKey in config) {
|
|
27
|
+
if (config.hasOwnProperty(propertyKey)) {
|
|
28
|
+
const {
|
|
29
|
+
key,
|
|
30
|
+
inputType,
|
|
31
|
+
default: defaultValue,
|
|
32
|
+
} = config[
|
|
33
|
+
propertyKey as keyof ConfluencePageConfig.ConfluencePerPageConfig
|
|
34
|
+
];
|
|
35
|
+
const frontmatterValue = frontmatter[key];
|
|
36
|
+
|
|
37
|
+
if (frontmatterValue !== undefined) {
|
|
38
|
+
result[propertyKey as keyof ConfluencePerPageUIValues] = {
|
|
39
|
+
value: frontmatterValue,
|
|
40
|
+
isSet: true,
|
|
41
|
+
};
|
|
42
|
+
} else {
|
|
43
|
+
switch (inputType) {
|
|
44
|
+
case "options":
|
|
45
|
+
case "array-text":
|
|
46
|
+
result[propertyKey as keyof ConfluencePerPageUIValues] =
|
|
47
|
+
{ value: defaultValue as never, isSet: false };
|
|
48
|
+
break;
|
|
49
|
+
case "boolean":
|
|
50
|
+
case "text":
|
|
51
|
+
result[propertyKey as keyof ConfluencePerPageUIValues] =
|
|
52
|
+
{ value: undefined, isSet: false };
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
throw new Error("Missing case for inputType");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result as ConfluencePerPageUIValues;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface FormProps {
|
|
64
|
+
config: ConfluencePageConfig.ConfluencePerPageConfig;
|
|
65
|
+
initialValues: ConfluencePerPageUIValues;
|
|
66
|
+
onSubmit: (values: ConfluencePerPageUIValues) => void;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface ModalProps {
|
|
70
|
+
config: ConfluencePageConfig.ConfluencePerPageConfig;
|
|
71
|
+
initialValues: ConfluencePerPageUIValues;
|
|
72
|
+
onSubmit: (values: ConfluencePerPageUIValues, close: () => void) => void;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const handleChange = (
|
|
76
|
+
key: string,
|
|
77
|
+
value: unknown,
|
|
78
|
+
inputValidator: ConfluencePageConfig.InputValidator<unknown>,
|
|
79
|
+
setValues: React.Dispatch<React.SetStateAction<ConfluencePerPageUIValues>>,
|
|
80
|
+
setErrors: React.Dispatch<React.SetStateAction<Record<string, Error[]>>>,
|
|
81
|
+
isSetValue: boolean,
|
|
82
|
+
) => {
|
|
83
|
+
const validationResult = inputValidator(value);
|
|
84
|
+
|
|
85
|
+
setValues((prevValues) => ({
|
|
86
|
+
...prevValues,
|
|
87
|
+
[key]: {
|
|
88
|
+
...prevValues[key as keyof ConfluencePerPageUIValues],
|
|
89
|
+
...(isSetValue ? { isSet: value } : { value }),
|
|
90
|
+
},
|
|
91
|
+
}));
|
|
92
|
+
setErrors((prevErrors) => ({
|
|
93
|
+
...prevErrors,
|
|
94
|
+
[key]: validationResult.valid ? [] : validationResult.errors,
|
|
95
|
+
}));
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const styles = {
|
|
99
|
+
errorTd: {
|
|
100
|
+
columnSpan: "all" as Property.ColumnSpan,
|
|
101
|
+
color: "red",
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const renderTextInput = (
|
|
106
|
+
key: string,
|
|
107
|
+
config: ConfluencePageConfig.FrontmatterConfig<string, "text">,
|
|
108
|
+
values: ConfluencePerPageUIValues,
|
|
109
|
+
errors: Record<string, Error[]>,
|
|
110
|
+
setValues: React.Dispatch<React.SetStateAction<ConfluencePerPageUIValues>>,
|
|
111
|
+
setErrors: React.Dispatch<React.SetStateAction<Record<string, Error[]>>>,
|
|
112
|
+
) => (
|
|
113
|
+
<>
|
|
114
|
+
<tr key={key}>
|
|
115
|
+
<td>
|
|
116
|
+
<label htmlFor={key}>{config.key}</label>
|
|
117
|
+
</td>
|
|
118
|
+
<td>
|
|
119
|
+
<input
|
|
120
|
+
type="text"
|
|
121
|
+
id={key}
|
|
122
|
+
value={
|
|
123
|
+
(values[key as keyof ConfluencePerPageUIValues]
|
|
124
|
+
.value as string) ?? ""
|
|
125
|
+
}
|
|
126
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
|
127
|
+
handleChange(
|
|
128
|
+
key,
|
|
129
|
+
e.target.value,
|
|
130
|
+
config.inputValidator,
|
|
131
|
+
setValues,
|
|
132
|
+
setErrors,
|
|
133
|
+
false,
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
/>
|
|
137
|
+
</td>
|
|
138
|
+
<td>
|
|
139
|
+
<input
|
|
140
|
+
type="checkbox"
|
|
141
|
+
id={`${key}-isSet`}
|
|
142
|
+
checked={
|
|
143
|
+
values[key as keyof ConfluencePerPageUIValues]
|
|
144
|
+
.isSet as boolean
|
|
145
|
+
}
|
|
146
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
|
147
|
+
handleChange(
|
|
148
|
+
key,
|
|
149
|
+
e.target.checked,
|
|
150
|
+
config.inputValidator,
|
|
151
|
+
setValues,
|
|
152
|
+
setErrors,
|
|
153
|
+
true,
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
/>
|
|
157
|
+
</td>
|
|
158
|
+
</tr>
|
|
159
|
+
<tr key={`${key}-errors`}>
|
|
160
|
+
{(errors[key]?.length ?? 0) > 0 && (
|
|
161
|
+
<td colSpan={3}>
|
|
162
|
+
<div className="error" style={styles.errorTd}>
|
|
163
|
+
{(errors[key] ?? []).map((error) => (
|
|
164
|
+
<p key={error.message}>{error.message}</p>
|
|
165
|
+
))}
|
|
166
|
+
</div>
|
|
167
|
+
</td>
|
|
168
|
+
)}
|
|
169
|
+
</tr>
|
|
170
|
+
</>
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
const renderArrayText = (
|
|
174
|
+
key: string,
|
|
175
|
+
config: ConfluencePageConfig.FrontmatterConfig<string[], "array-text">,
|
|
176
|
+
values: ConfluencePerPageUIValues,
|
|
177
|
+
errors: Record<string, Error[]>,
|
|
178
|
+
setValues: React.Dispatch<React.SetStateAction<ConfluencePerPageUIValues>>,
|
|
179
|
+
setErrors: React.Dispatch<React.SetStateAction<Record<string, Error[]>>>,
|
|
180
|
+
) => (
|
|
181
|
+
<>
|
|
182
|
+
<tr key={key}>
|
|
183
|
+
<td>
|
|
184
|
+
<label htmlFor={key}>{config.key}</label>
|
|
185
|
+
</td>
|
|
186
|
+
<td>
|
|
187
|
+
{(
|
|
188
|
+
values[key as keyof ConfluencePerPageUIValues]
|
|
189
|
+
.value as unknown as string[]
|
|
190
|
+
).map((value, index) => (
|
|
191
|
+
<input
|
|
192
|
+
key={`${key}-${index}`}
|
|
193
|
+
type="text"
|
|
194
|
+
value={value}
|
|
195
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) => {
|
|
196
|
+
const newArray = [
|
|
197
|
+
...(values[
|
|
198
|
+
key as keyof ConfluencePerPageUIValues
|
|
199
|
+
].value as unknown as string[]),
|
|
200
|
+
];
|
|
201
|
+
newArray[index] = e.target.value;
|
|
202
|
+
handleChange(
|
|
203
|
+
key,
|
|
204
|
+
newArray,
|
|
205
|
+
config.inputValidator,
|
|
206
|
+
setValues,
|
|
207
|
+
setErrors,
|
|
208
|
+
false,
|
|
209
|
+
);
|
|
210
|
+
}}
|
|
211
|
+
/>
|
|
212
|
+
))}
|
|
213
|
+
<button
|
|
214
|
+
type="button"
|
|
215
|
+
onClick={() => {
|
|
216
|
+
const newArray = [
|
|
217
|
+
...(values[key as keyof ConfluencePerPageUIValues]
|
|
218
|
+
.value as string[]),
|
|
219
|
+
"",
|
|
220
|
+
];
|
|
221
|
+
handleChange(
|
|
222
|
+
key,
|
|
223
|
+
newArray,
|
|
224
|
+
config.inputValidator,
|
|
225
|
+
setValues,
|
|
226
|
+
setErrors,
|
|
227
|
+
false,
|
|
228
|
+
);
|
|
229
|
+
}}
|
|
230
|
+
>
|
|
231
|
+
+
|
|
232
|
+
</button>
|
|
233
|
+
</td>
|
|
234
|
+
<td>
|
|
235
|
+
<input
|
|
236
|
+
type="checkbox"
|
|
237
|
+
id={`${key}-isSet`}
|
|
238
|
+
checked={
|
|
239
|
+
values[key as keyof ConfluencePerPageUIValues]
|
|
240
|
+
.isSet as boolean
|
|
241
|
+
}
|
|
242
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
|
243
|
+
handleChange(
|
|
244
|
+
key,
|
|
245
|
+
e.target.checked,
|
|
246
|
+
config.inputValidator,
|
|
247
|
+
setValues,
|
|
248
|
+
setErrors,
|
|
249
|
+
true,
|
|
250
|
+
)
|
|
251
|
+
}
|
|
252
|
+
/>
|
|
253
|
+
</td>
|
|
254
|
+
</tr>
|
|
255
|
+
<tr key={`${key}-errors`}>
|
|
256
|
+
{(errors[key]?.length ?? 0) > 0 && (
|
|
257
|
+
<td colSpan={3}>
|
|
258
|
+
<div className="error" style={styles.errorTd}>
|
|
259
|
+
{(errors[key] ?? []).map((error) => (
|
|
260
|
+
<p key={error.message}>{error.message}</p>
|
|
261
|
+
))}
|
|
262
|
+
</div>
|
|
263
|
+
</td>
|
|
264
|
+
)}
|
|
265
|
+
</tr>
|
|
266
|
+
</>
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
const renderBoolean = (
|
|
270
|
+
key: string,
|
|
271
|
+
config: ConfluencePageConfig.FrontmatterConfig<boolean, "boolean">,
|
|
272
|
+
values: ConfluencePerPageUIValues,
|
|
273
|
+
errors: Record<string, Error[]>,
|
|
274
|
+
setValues: React.Dispatch<React.SetStateAction<ConfluencePerPageUIValues>>,
|
|
275
|
+
setErrors: React.Dispatch<React.SetStateAction<Record<string, Error[]>>>,
|
|
276
|
+
) => (
|
|
277
|
+
<>
|
|
278
|
+
<tr key={key}>
|
|
279
|
+
<td>
|
|
280
|
+
<label htmlFor={key}>{config.key}</label>
|
|
281
|
+
</td>
|
|
282
|
+
<td>
|
|
283
|
+
<input
|
|
284
|
+
type="checkbox"
|
|
285
|
+
id={key}
|
|
286
|
+
checked={
|
|
287
|
+
values[key as keyof ConfluencePerPageUIValues]
|
|
288
|
+
.value as boolean
|
|
289
|
+
}
|
|
290
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
|
291
|
+
handleChange(
|
|
292
|
+
key,
|
|
293
|
+
e.target.checked,
|
|
294
|
+
config.inputValidator,
|
|
295
|
+
setValues,
|
|
296
|
+
setErrors,
|
|
297
|
+
false,
|
|
298
|
+
)
|
|
299
|
+
}
|
|
300
|
+
/>
|
|
301
|
+
</td>
|
|
302
|
+
<td>
|
|
303
|
+
<input
|
|
304
|
+
type="checkbox"
|
|
305
|
+
id={`${key}-isSet`}
|
|
306
|
+
checked={
|
|
307
|
+
values[key as keyof ConfluencePerPageUIValues]
|
|
308
|
+
.isSet as boolean
|
|
309
|
+
}
|
|
310
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
|
311
|
+
handleChange(
|
|
312
|
+
key,
|
|
313
|
+
e.target.checked,
|
|
314
|
+
config.inputValidator,
|
|
315
|
+
setValues,
|
|
316
|
+
setErrors,
|
|
317
|
+
true,
|
|
318
|
+
)
|
|
319
|
+
}
|
|
320
|
+
/>
|
|
321
|
+
</td>
|
|
322
|
+
</tr>
|
|
323
|
+
<tr key={`${key}-errors`}>
|
|
324
|
+
{(errors[key]?.length ?? 0) > 0 && (
|
|
325
|
+
<td colSpan={3}>
|
|
326
|
+
<div className="error" style={styles.errorTd}>
|
|
327
|
+
{(errors[key] ?? []).map((error) => (
|
|
328
|
+
<p key={error.message}>{error.message}</p>
|
|
329
|
+
))}
|
|
330
|
+
</div>
|
|
331
|
+
</td>
|
|
332
|
+
)}
|
|
333
|
+
</tr>
|
|
334
|
+
</>
|
|
335
|
+
);
|
|
336
|
+
const renderOptions = (
|
|
337
|
+
key: string,
|
|
338
|
+
config: ConfluencePageConfig.FrontmatterConfig<
|
|
339
|
+
ConfluencePageConfig.PageContentType,
|
|
340
|
+
"options"
|
|
341
|
+
>,
|
|
342
|
+
values: ConfluencePerPageUIValues,
|
|
343
|
+
errors: Record<string, Error[]>,
|
|
344
|
+
setValues: React.Dispatch<React.SetStateAction<ConfluencePerPageUIValues>>,
|
|
345
|
+
setErrors: React.Dispatch<React.SetStateAction<Record<string, Error[]>>>,
|
|
346
|
+
) => (
|
|
347
|
+
<>
|
|
348
|
+
<tr key={key}>
|
|
349
|
+
<td>
|
|
350
|
+
<label htmlFor={key}>{config.key}</label>
|
|
351
|
+
</td>
|
|
352
|
+
<td>
|
|
353
|
+
<select
|
|
354
|
+
id={key}
|
|
355
|
+
value={
|
|
356
|
+
values[key as keyof ConfluencePerPageUIValues]
|
|
357
|
+
.value as ConfluencePageConfig.PageContentType
|
|
358
|
+
}
|
|
359
|
+
onChange={(e: ChangeEvent<HTMLSelectElement>) =>
|
|
360
|
+
handleChange(
|
|
361
|
+
key,
|
|
362
|
+
e.target
|
|
363
|
+
.value as ConfluencePageConfig.PageContentType,
|
|
364
|
+
config.inputValidator,
|
|
365
|
+
setValues,
|
|
366
|
+
setErrors,
|
|
367
|
+
false,
|
|
368
|
+
)
|
|
369
|
+
}
|
|
370
|
+
>
|
|
371
|
+
{config.selectOptions.map((option) => (
|
|
372
|
+
<option key={option} value={option}>
|
|
373
|
+
{option}
|
|
374
|
+
</option>
|
|
375
|
+
))}
|
|
376
|
+
</select>
|
|
377
|
+
</td>
|
|
378
|
+
<td>
|
|
379
|
+
<input
|
|
380
|
+
type="checkbox"
|
|
381
|
+
id={`${key}-isSet`}
|
|
382
|
+
checked={
|
|
383
|
+
values[key as keyof ConfluencePerPageUIValues]
|
|
384
|
+
.isSet as boolean
|
|
385
|
+
}
|
|
386
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
|
387
|
+
handleChange(
|
|
388
|
+
key,
|
|
389
|
+
e.target.checked,
|
|
390
|
+
config.inputValidator,
|
|
391
|
+
setValues,
|
|
392
|
+
setErrors,
|
|
393
|
+
true,
|
|
394
|
+
)
|
|
395
|
+
}
|
|
396
|
+
/>
|
|
397
|
+
</td>
|
|
398
|
+
</tr>
|
|
399
|
+
<tr key={`${key}-errors`}>
|
|
400
|
+
{(errors[key]?.length ?? 0) > 0 && (
|
|
401
|
+
<td colSpan={3}>
|
|
402
|
+
<div className="error" style={styles.errorTd}>
|
|
403
|
+
{(errors[key] ?? []).map((error) => (
|
|
404
|
+
<p key={error.message}>{error.message}</p>
|
|
405
|
+
))}
|
|
406
|
+
</div>
|
|
407
|
+
</td>
|
|
408
|
+
)}
|
|
409
|
+
</tr>
|
|
410
|
+
</>
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
const ConfluenceForm: React.FC<FormProps> = ({
|
|
414
|
+
config,
|
|
415
|
+
initialValues,
|
|
416
|
+
onSubmit,
|
|
417
|
+
}) => {
|
|
418
|
+
const [values, setValues] =
|
|
419
|
+
useState<ConfluencePerPageUIValues>(initialValues);
|
|
420
|
+
const [errors, setErrors] = useState<Record<string, Error[]>>({});
|
|
421
|
+
|
|
422
|
+
const handleSubmit = (e: React.FormEvent) => {
|
|
423
|
+
e.preventDefault();
|
|
424
|
+
onSubmit(values as ConfluencePerPageUIValues);
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
return (
|
|
428
|
+
<form onSubmit={handleSubmit}>
|
|
429
|
+
<h1>Update Confluence Page Settings</h1>
|
|
430
|
+
<table>
|
|
431
|
+
<thead>
|
|
432
|
+
<tr>
|
|
433
|
+
<td>YAML Key</td>
|
|
434
|
+
<td>Value</td>
|
|
435
|
+
<td>Update</td>
|
|
436
|
+
</tr>
|
|
437
|
+
</thead>
|
|
438
|
+
<tbody>
|
|
439
|
+
{Object.entries(config).map(([key, config]) => {
|
|
440
|
+
switch (config.inputType) {
|
|
441
|
+
case "text":
|
|
442
|
+
return renderTextInput(
|
|
443
|
+
key,
|
|
444
|
+
config as ConfluencePageConfig.FrontmatterConfig<
|
|
445
|
+
string,
|
|
446
|
+
"text"
|
|
447
|
+
>,
|
|
448
|
+
values,
|
|
449
|
+
errors,
|
|
450
|
+
setValues,
|
|
451
|
+
setErrors,
|
|
452
|
+
);
|
|
453
|
+
case "array-text":
|
|
454
|
+
return renderArrayText(
|
|
455
|
+
key,
|
|
456
|
+
config as ConfluencePageConfig.FrontmatterConfig<
|
|
457
|
+
string[],
|
|
458
|
+
"array-text"
|
|
459
|
+
>,
|
|
460
|
+
values,
|
|
461
|
+
errors,
|
|
462
|
+
setValues,
|
|
463
|
+
setErrors,
|
|
464
|
+
);
|
|
465
|
+
case "boolean":
|
|
466
|
+
return renderBoolean(
|
|
467
|
+
key,
|
|
468
|
+
config as ConfluencePageConfig.FrontmatterConfig<
|
|
469
|
+
boolean,
|
|
470
|
+
"boolean"
|
|
471
|
+
>,
|
|
472
|
+
values,
|
|
473
|
+
errors,
|
|
474
|
+
setValues,
|
|
475
|
+
setErrors,
|
|
476
|
+
);
|
|
477
|
+
case "options":
|
|
478
|
+
return renderOptions(
|
|
479
|
+
key,
|
|
480
|
+
config as ConfluencePageConfig.FrontmatterConfig<
|
|
481
|
+
ConfluencePageConfig.PageContentType,
|
|
482
|
+
"options"
|
|
483
|
+
>,
|
|
484
|
+
values,
|
|
485
|
+
errors,
|
|
486
|
+
setValues,
|
|
487
|
+
setErrors,
|
|
488
|
+
);
|
|
489
|
+
default:
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
})}
|
|
493
|
+
</tbody>
|
|
494
|
+
</table>
|
|
495
|
+
<button type="submit">Submit</button>
|
|
496
|
+
</form>
|
|
497
|
+
);
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
export class ConfluencePerPageForm extends Modal {
|
|
501
|
+
modalProps: ModalProps;
|
|
502
|
+
|
|
503
|
+
constructor(app: App, modalProps: ModalProps) {
|
|
504
|
+
super(app);
|
|
505
|
+
this.modalProps = modalProps;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
override onOpen() {
|
|
509
|
+
const { contentEl } = this;
|
|
510
|
+
const test: FormProps = {
|
|
511
|
+
...this.modalProps,
|
|
512
|
+
onSubmit: (values) => {
|
|
513
|
+
const boundClose = this.close.bind(this);
|
|
514
|
+
this.modalProps.onSubmit(values, boundClose);
|
|
515
|
+
},
|
|
516
|
+
};
|
|
517
|
+
ReactDOM.render(React.createElement(ConfluenceForm, test), contentEl);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
override onClose() {
|
|
521
|
+
const { contentEl } = this;
|
|
522
|
+
ReactDOM.unmountComponentAtNode(contentEl);
|
|
523
|
+
contentEl.empty();
|
|
524
|
+
}
|
|
525
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { App, Setting, PluginSettingTab } from "obsidian";
|
|
2
|
+
import ConfluencePlugin from "./main";
|
|
3
|
+
|
|
4
|
+
export class ConfluenceSettingTab extends PluginSettingTab {
|
|
5
|
+
plugin: ConfluencePlugin;
|
|
6
|
+
|
|
7
|
+
constructor(app: App, plugin: ConfluencePlugin) {
|
|
8
|
+
super(app, plugin);
|
|
9
|
+
this.plugin = plugin;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
display(): void {
|
|
13
|
+
const { containerEl } = this;
|
|
14
|
+
|
|
15
|
+
containerEl.empty();
|
|
16
|
+
|
|
17
|
+
containerEl.createEl("h2", {
|
|
18
|
+
text: "Settings for connecting to Atlassian Confluence",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
new Setting(containerEl)
|
|
22
|
+
.setName("Confluence Domain")
|
|
23
|
+
.setDesc('Confluence Domain eg "https://mysite.atlassian.net"')
|
|
24
|
+
.addText((text) =>
|
|
25
|
+
text
|
|
26
|
+
.setPlaceholder("https://mysite.atlassian.net")
|
|
27
|
+
.setValue(this.plugin.settings.confluenceBaseUrl)
|
|
28
|
+
.onChange(async (value) => {
|
|
29
|
+
this.plugin.settings.confluenceBaseUrl = value;
|
|
30
|
+
await this.plugin.saveSettings();
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
new Setting(containerEl)
|
|
35
|
+
.setName("Atlassian Username")
|
|
36
|
+
.setDesc('eg "username@domain.com"')
|
|
37
|
+
.addText((text) =>
|
|
38
|
+
text
|
|
39
|
+
.setPlaceholder("username@domain.com")
|
|
40
|
+
.setValue(this.plugin.settings.atlassianUserName)
|
|
41
|
+
.onChange(async (value) => {
|
|
42
|
+
this.plugin.settings.atlassianUserName = value;
|
|
43
|
+
await this.plugin.saveSettings();
|
|
44
|
+
}),
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
new Setting(containerEl)
|
|
48
|
+
.setName("Atlassian API Token")
|
|
49
|
+
.setDesc("")
|
|
50
|
+
.addText((text) =>
|
|
51
|
+
text
|
|
52
|
+
.setPlaceholder("")
|
|
53
|
+
.setValue(this.plugin.settings.atlassianApiToken)
|
|
54
|
+
.onChange(async (value) => {
|
|
55
|
+
this.plugin.settings.atlassianApiToken = value;
|
|
56
|
+
await this.plugin.saveSettings();
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
new Setting(containerEl)
|
|
61
|
+
.setName("Confluence Parent Page ID")
|
|
62
|
+
.setDesc("Page ID to publish files under")
|
|
63
|
+
.addText((text) =>
|
|
64
|
+
text
|
|
65
|
+
.setPlaceholder("23232345645")
|
|
66
|
+
.setValue(this.plugin.settings.confluenceParentId)
|
|
67
|
+
.onChange(async (value) => {
|
|
68
|
+
this.plugin.settings.confluenceParentId = value;
|
|
69
|
+
await this.plugin.saveSettings();
|
|
70
|
+
}),
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
new Setting(containerEl)
|
|
74
|
+
.setName("Folder to publish")
|
|
75
|
+
.setDesc(
|
|
76
|
+
"Publish all files except notes that are excluded using YAML Frontmatter",
|
|
77
|
+
)
|
|
78
|
+
.addText((text) =>
|
|
79
|
+
text
|
|
80
|
+
.setPlaceholder("")
|
|
81
|
+
.setValue(this.plugin.settings.folderToPublish)
|
|
82
|
+
.onChange(async (value) => {
|
|
83
|
+
this.plugin.settings.folderToPublish = value;
|
|
84
|
+
await this.plugin.saveSettings();
|
|
85
|
+
}),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
new Setting(containerEl)
|
|
89
|
+
.setName("First Header Page Name")
|
|
90
|
+
.setDesc("First header replaces file name as page title")
|
|
91
|
+
.addToggle((toggle) =>
|
|
92
|
+
toggle
|
|
93
|
+
.setValue(this.plugin.settings.firstHeadingPageTitle)
|
|
94
|
+
.onChange(async (value) => {
|
|
95
|
+
this.plugin.settings.firstHeadingPageTitle = value;
|
|
96
|
+
await this.plugin.saveSettings();
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
new Setting(containerEl)
|
|
101
|
+
.setName("Mermaid Diagram Theme")
|
|
102
|
+
.setDesc("Pick the theme to apply to mermaid diagrams")
|
|
103
|
+
.addDropdown((dropdown) => {
|
|
104
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
105
|
+
dropdown
|
|
106
|
+
.addOptions({
|
|
107
|
+
"match-obsidian": "Match Obsidian",
|
|
108
|
+
"light-obsidian": "Obsidian Theme - Light",
|
|
109
|
+
"dark-obsidian": "Obsidian Theme - Dark",
|
|
110
|
+
default: "Mermaid - Default",
|
|
111
|
+
neutral: "Mermaid - Neutral",
|
|
112
|
+
dark: "Mermaid - Dark",
|
|
113
|
+
forest: "Mermaid - Forest",
|
|
114
|
+
})
|
|
115
|
+
.setValue(this.plugin.settings.mermaidTheme)
|
|
116
|
+
.onChange(async (value) => {
|
|
117
|
+
// @ts-expect-error
|
|
118
|
+
this.plugin.settings.mermaidTheme = value;
|
|
119
|
+
await this.plugin.saveSettings();
|
|
120
|
+
});
|
|
121
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|