kviewer 0.0.1
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/README.md +134 -0
- package/dist/module.d.mts +15 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +26 -0
- package/dist/runtime/annotation/engine/config.d.ts +52 -0
- package/dist/runtime/annotation/engine/config.js +283 -0
- package/dist/runtime/annotation/engine/const.d.ts +6 -0
- package/dist/runtime/annotation/engine/const.js +7 -0
- package/dist/runtime/annotation/engine/cursor-preview.d.ts +2 -0
- package/dist/runtime/annotation/engine/cursor-preview.js +88 -0
- package/dist/runtime/annotation/engine/editor/editor.d.ts +69 -0
- package/dist/runtime/annotation/engine/editor/editor.js +233 -0
- package/dist/runtime/annotation/engine/editor/selector.d.ts +74 -0
- package/dist/runtime/annotation/engine/editor/selector.js +594 -0
- package/dist/runtime/annotation/engine/import-normalize.d.ts +5 -0
- package/dist/runtime/annotation/engine/import-normalize.js +99 -0
- package/dist/runtime/annotation/engine/input-device.d.ts +53 -0
- package/dist/runtime/annotation/engine/input-device.js +64 -0
- package/dist/runtime/annotation/engine/painter.d.ts +97 -0
- package/dist/runtime/annotation/engine/painter.js +591 -0
- package/dist/runtime/annotation/engine/store.d.ts +11 -0
- package/dist/runtime/annotation/engine/store.js +47 -0
- package/dist/runtime/annotation/engine/tools/arrow.d.ts +22 -0
- package/dist/runtime/annotation/engine/tools/arrow.js +126 -0
- package/dist/runtime/annotation/engine/tools/circle.d.ts +45 -0
- package/dist/runtime/annotation/engine/tools/circle.js +148 -0
- package/dist/runtime/annotation/engine/tools/cloud.d.ts +50 -0
- package/dist/runtime/annotation/engine/tools/cloud.js +244 -0
- package/dist/runtime/annotation/engine/tools/free-highlight.d.ts +43 -0
- package/dist/runtime/annotation/engine/tools/free-highlight.js +165 -0
- package/dist/runtime/annotation/engine/tools/free-text.d.ts +27 -0
- package/dist/runtime/annotation/engine/tools/free-text.js +114 -0
- package/dist/runtime/annotation/engine/tools/freehand.d.ts +44 -0
- package/dist/runtime/annotation/engine/tools/freehand.js +151 -0
- package/dist/runtime/annotation/engine/tools/highlight.d.ts +87 -0
- package/dist/runtime/annotation/engine/tools/highlight.js +215 -0
- package/dist/runtime/annotation/engine/tools/note.d.ts +9 -0
- package/dist/runtime/annotation/engine/tools/note.js +34 -0
- package/dist/runtime/annotation/engine/tools/rectangle.d.ts +45 -0
- package/dist/runtime/annotation/engine/tools/rectangle.js +142 -0
- package/dist/runtime/annotation/engine/tools/signature.d.ts +16 -0
- package/dist/runtime/annotation/engine/tools/signature.js +74 -0
- package/dist/runtime/annotation/engine/tools/stamp.d.ts +18 -0
- package/dist/runtime/annotation/engine/tools/stamp.js +94 -0
- package/dist/runtime/annotation/engine/types.d.ts +170 -0
- package/dist/runtime/annotation/engine/types.js +67 -0
- package/dist/runtime/annotation/engine/utils.d.ts +40 -0
- package/dist/runtime/annotation/engine/utils.js +257 -0
- package/dist/runtime/annotation/parsers/parseFormFields.d.ts +9 -0
- package/dist/runtime/annotation/parsers/parseFormFields.js +101 -0
- package/dist/runtime/annotation/pdf-export/download.d.ts +1 -0
- package/dist/runtime/annotation/pdf-export/download.js +10 -0
- package/dist/runtime/annotation/pdf-export/export-form-fields.d.ts +9 -0
- package/dist/runtime/annotation/pdf-export/export-form-fields.js +90 -0
- package/dist/runtime/annotation/pdf-export/export.d.ts +15 -0
- package/dist/runtime/annotation/pdf-export/export.js +145 -0
- package/dist/runtime/annotation/pdf-export/parse.d.ts +10 -0
- package/dist/runtime/annotation/pdf-export/parse.js +19 -0
- package/dist/runtime/annotation/pdf-export/parse_circle.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_circle.js +41 -0
- package/dist/runtime/annotation/pdf-export/parse_freetext.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_freetext.js +54 -0
- package/dist/runtime/annotation/pdf-export/parse_highlight.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_highlight.js +134 -0
- package/dist/runtime/annotation/pdf-export/parse_ink.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_ink.js +124 -0
- package/dist/runtime/annotation/pdf-export/parse_line.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_line.js +71 -0
- package/dist/runtime/annotation/pdf-export/parse_polyline.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_polyline.js +93 -0
- package/dist/runtime/annotation/pdf-export/parse_square.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_square.js +41 -0
- package/dist/runtime/annotation/pdf-export/parse_stamp.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_stamp.js +195 -0
- package/dist/runtime/annotation/pdf-export/parse_strikeout.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_strikeout.js +59 -0
- package/dist/runtime/annotation/pdf-export/parse_text.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_text.js +42 -0
- package/dist/runtime/annotation/pdf-export/parse_underline.d.ts +4 -0
- package/dist/runtime/annotation/pdf-export/parse_underline.js +59 -0
- package/dist/runtime/assets/kviewer.css +1 -0
- package/dist/runtime/components/AnnotationToolbar.d.vue.ts +3 -0
- package/dist/runtime/components/AnnotationToolbar.vue +125 -0
- package/dist/runtime/components/AnnotationToolbar.vue.d.ts +3 -0
- package/dist/runtime/components/FloatingPageIndicator.d.vue.ts +6 -0
- package/dist/runtime/components/FloatingPageIndicator.vue +93 -0
- package/dist/runtime/components/FloatingPageIndicator.vue.d.ts +6 -0
- package/dist/runtime/components/FormFieldLayer.d.vue.ts +11 -0
- package/dist/runtime/components/FormFieldLayer.vue +40 -0
- package/dist/runtime/components/FormFieldLayer.vue.d.ts +11 -0
- package/dist/runtime/components/PdfPage.d.vue.ts +9 -0
- package/dist/runtime/components/PdfPage.vue +199 -0
- package/dist/runtime/components/PdfPage.vue.d.ts +9 -0
- package/dist/runtime/components/ToolButton.d.vue.ts +13 -0
- package/dist/runtime/components/ToolButton.vue +26 -0
- package/dist/runtime/components/ToolButton.vue.d.ts +13 -0
- package/dist/runtime/components/Toolbar.d.vue.ts +3 -0
- package/dist/runtime/components/Toolbar.vue +11 -0
- package/dist/runtime/components/Toolbar.vue.d.ts +3 -0
- package/dist/runtime/components/Viewer.d.vue.ts +45 -0
- package/dist/runtime/components/Viewer.vue +617 -0
- package/dist/runtime/components/Viewer.vue.d.ts +45 -0
- package/dist/runtime/components/ViewerBar.d.vue.ts +3 -0
- package/dist/runtime/components/ViewerBar.vue +91 -0
- package/dist/runtime/components/ViewerBar.vue.d.ts +3 -0
- package/dist/runtime/components/ViewerTabs.d.vue.ts +381 -0
- package/dist/runtime/components/ViewerTabs.vue +171 -0
- package/dist/runtime/components/ViewerTabs.vue.d.ts +381 -0
- package/dist/runtime/components/form-fields/FormButton.d.vue.ts +7 -0
- package/dist/runtime/components/form-fields/FormButton.vue +39 -0
- package/dist/runtime/components/form-fields/FormButton.vue.d.ts +7 -0
- package/dist/runtime/components/form-fields/FormCheckbox.d.vue.ts +7 -0
- package/dist/runtime/components/form-fields/FormCheckbox.vue +28 -0
- package/dist/runtime/components/form-fields/FormCheckbox.vue.d.ts +7 -0
- package/dist/runtime/components/form-fields/FormDropdown.d.vue.ts +7 -0
- package/dist/runtime/components/form-fields/FormDropdown.vue +112 -0
- package/dist/runtime/components/form-fields/FormDropdown.vue.d.ts +7 -0
- package/dist/runtime/components/form-fields/FormFieldWrapper.d.vue.ts +8 -0
- package/dist/runtime/components/form-fields/FormFieldWrapper.vue +41 -0
- package/dist/runtime/components/form-fields/FormFieldWrapper.vue.d.ts +8 -0
- package/dist/runtime/components/form-fields/FormRadioButton.d.vue.ts +7 -0
- package/dist/runtime/components/form-fields/FormRadioButton.vue +30 -0
- package/dist/runtime/components/form-fields/FormRadioButton.vue.d.ts +7 -0
- package/dist/runtime/components/form-fields/FormSignatureField.d.vue.ts +7 -0
- package/dist/runtime/components/form-fields/FormSignatureField.vue +54 -0
- package/dist/runtime/components/form-fields/FormSignatureField.vue.d.ts +7 -0
- package/dist/runtime/components/form-fields/FormTextField.d.vue.ts +7 -0
- package/dist/runtime/components/form-fields/FormTextField.vue +66 -0
- package/dist/runtime/components/form-fields/FormTextField.vue.d.ts +7 -0
- package/dist/runtime/components/modals/FreeTextModal.d.vue.ts +25 -0
- package/dist/runtime/components/modals/FreeTextModal.vue +89 -0
- package/dist/runtime/components/modals/FreeTextModal.vue.d.ts +25 -0
- package/dist/runtime/components/modals/SignatureDrawModal.d.vue.ts +14 -0
- package/dist/runtime/components/modals/SignatureDrawModal.vue +120 -0
- package/dist/runtime/components/modals/SignatureDrawModal.vue.d.ts +14 -0
- package/dist/runtime/components/panels/SignaturePicker.d.vue.ts +3 -0
- package/dist/runtime/components/panels/SignaturePicker.vue +85 -0
- package/dist/runtime/components/panels/SignaturePicker.vue.d.ts +3 -0
- package/dist/runtime/components/panels/StampPicker.d.vue.ts +3 -0
- package/dist/runtime/components/panels/StampPicker.vue +46 -0
- package/dist/runtime/components/panels/StampPicker.vue.d.ts +3 -0
- package/dist/runtime/components/tools/ActionTools.d.vue.ts +3 -0
- package/dist/runtime/components/tools/ActionTools.vue +32 -0
- package/dist/runtime/components/tools/ActionTools.vue.d.ts +3 -0
- package/dist/runtime/components/tools/DrawingTools.d.vue.ts +6 -0
- package/dist/runtime/components/tools/DrawingTools.vue +57 -0
- package/dist/runtime/components/tools/DrawingTools.vue.d.ts +6 -0
- package/dist/runtime/components/tools/HandTool.d.vue.ts +3 -0
- package/dist/runtime/components/tools/HandTool.vue +14 -0
- package/dist/runtime/components/tools/HandTool.vue.d.ts +3 -0
- package/dist/runtime/components/tools/MarqueeTool.d.vue.ts +3 -0
- package/dist/runtime/components/tools/MarqueeTool.vue +15 -0
- package/dist/runtime/components/tools/MarqueeTool.vue.d.ts +3 -0
- package/dist/runtime/components/tools/PageInfo.d.vue.ts +3 -0
- package/dist/runtime/components/tools/PageInfo.vue +10 -0
- package/dist/runtime/components/tools/PageInfo.vue.d.ts +3 -0
- package/dist/runtime/components/tools/PageSettings.d.vue.ts +3 -0
- package/dist/runtime/components/tools/PageSettings.vue +92 -0
- package/dist/runtime/components/tools/PageSettings.vue.d.ts +3 -0
- package/dist/runtime/components/tools/SearchTool.d.vue.ts +3 -0
- package/dist/runtime/components/tools/SearchTool.vue +149 -0
- package/dist/runtime/components/tools/SearchTool.vue.d.ts +3 -0
- package/dist/runtime/components/tools/ToolProperties.d.vue.ts +7 -0
- package/dist/runtime/components/tools/ToolProperties.vue +174 -0
- package/dist/runtime/components/tools/ToolProperties.vue.d.ts +7 -0
- package/dist/runtime/components/tools/ZoomControls.d.vue.ts +3 -0
- package/dist/runtime/components/tools/ZoomControls.vue +59 -0
- package/dist/runtime/components/tools/ZoomControls.vue.d.ts +3 -0
- package/dist/runtime/composables/search-utils.d.ts +20 -0
- package/dist/runtime/composables/search-utils.js +55 -0
- package/dist/runtime/composables/useAnnotationEngine.d.ts +7 -0
- package/dist/runtime/composables/useAnnotationEngine.js +70 -0
- package/dist/runtime/composables/useAnnotationHistory.d.ts +12 -0
- package/dist/runtime/composables/useAnnotationHistory.js +69 -0
- package/dist/runtime/composables/useFormFields.d.ts +26 -0
- package/dist/runtime/composables/useFormFields.js +112 -0
- package/dist/runtime/composables/usePageProxyCache.d.ts +8 -0
- package/dist/runtime/composables/usePageProxyCache.js +73 -0
- package/dist/runtime/composables/usePageSettings.d.ts +16 -0
- package/dist/runtime/composables/usePageSettings.js +66 -0
- package/dist/runtime/composables/usePageVirtualization.d.ts +19 -0
- package/dist/runtime/composables/usePageVirtualization.js +203 -0
- package/dist/runtime/composables/useSearchIndex.d.ts +11 -0
- package/dist/runtime/composables/useSearchIndex.js +71 -0
- package/dist/runtime/composables/useViewerSearch.d.ts +32 -0
- package/dist/runtime/composables/useViewerSearch.js +418 -0
- package/dist/runtime/composables/useViewerState.d.ts +62 -0
- package/dist/runtime/composables/useViewerState.js +189 -0
- package/dist/runtime/composables/viewMode.d.ts +11 -0
- package/dist/runtime/composables/viewMode.js +19 -0
- package/dist/runtime/plugin.d.ts +2 -0
- package/dist/runtime/plugin.js +3 -0
- package/dist/runtime/public-types.d.ts +2 -0
- package/dist/runtime/public-types.js +0 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/types.d.mts +5 -0
- package/package.json +64 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="kviewer-form-field"
|
|
4
|
+
:style="positionStyle"
|
|
5
|
+
>
|
|
6
|
+
<FormTextField v-if="props.field.fieldType === 'text'" :field="props.field" />
|
|
7
|
+
<FormCheckbox v-else-if="props.field.fieldType === 'checkbox'" :field="props.field" />
|
|
8
|
+
<FormRadioButton v-else-if="props.field.fieldType === 'radio'" :field="props.field" />
|
|
9
|
+
<FormDropdown v-else-if="props.field.fieldType === 'dropdown'" :field="props.field" />
|
|
10
|
+
<FormSignatureField v-else-if="props.field.fieldType === 'signature'" :field="props.field" />
|
|
11
|
+
<FormButton v-else-if="props.field.fieldType === 'button'" :field="props.field" />
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup>
|
|
16
|
+
import { computed } from "vue";
|
|
17
|
+
import FormTextField from "./FormTextField.vue";
|
|
18
|
+
import FormCheckbox from "./FormCheckbox.vue";
|
|
19
|
+
import FormRadioButton from "./FormRadioButton.vue";
|
|
20
|
+
import FormDropdown from "./FormDropdown.vue";
|
|
21
|
+
import FormSignatureField from "./FormSignatureField.vue";
|
|
22
|
+
import FormButton from "./FormButton.vue";
|
|
23
|
+
const props = defineProps({
|
|
24
|
+
field: { type: Object, required: true },
|
|
25
|
+
pageHeight: { type: Number, required: true }
|
|
26
|
+
});
|
|
27
|
+
const positionStyle = computed(() => {
|
|
28
|
+
const rect = props.field.rect;
|
|
29
|
+
const left = rect[0];
|
|
30
|
+
const top = props.pageHeight - rect[3];
|
|
31
|
+
const width = rect[2] - rect[0];
|
|
32
|
+
const height = rect[3] - rect[1];
|
|
33
|
+
return {
|
|
34
|
+
position: "absolute",
|
|
35
|
+
left: `${left}px`,
|
|
36
|
+
top: `${top}px`,
|
|
37
|
+
width: `${width}px`,
|
|
38
|
+
height: `${height}px`
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
</script>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FormFieldDefinition } from '../../annotation/engine/types.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
field: FormFieldDefinition;
|
|
4
|
+
pageHeight: number;
|
|
5
|
+
};
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
7
|
+
declare const _default: typeof __VLS_export;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FormFieldDefinition } from '../../annotation/engine/types.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
field: FormFieldDefinition;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="kviewer-form-radio">
|
|
3
|
+
<input
|
|
4
|
+
type="radio"
|
|
5
|
+
:name="props.field.fieldName"
|
|
6
|
+
:value="props.field.buttonValue"
|
|
7
|
+
:checked="isSelected"
|
|
8
|
+
:disabled="props.field.readOnly"
|
|
9
|
+
:required="props.field.required"
|
|
10
|
+
@change="onChange"
|
|
11
|
+
>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup>
|
|
16
|
+
import { computed } from "vue";
|
|
17
|
+
import { useFormFields } from "../../composables/useFormFields";
|
|
18
|
+
const props = defineProps({
|
|
19
|
+
field: { type: Object, required: true }
|
|
20
|
+
});
|
|
21
|
+
const formFields = useFormFields();
|
|
22
|
+
const isSelected = computed(() => {
|
|
23
|
+
const fv = formFields.getFieldValue(props.field.id);
|
|
24
|
+
if (!fv) return false;
|
|
25
|
+
return fv.value === props.field.buttonValue && fv.value !== "";
|
|
26
|
+
});
|
|
27
|
+
function onChange() {
|
|
28
|
+
formFields.setFieldValue(props.field.id, props.field.buttonValue ?? "");
|
|
29
|
+
}
|
|
30
|
+
</script>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FormFieldDefinition } from '../../annotation/engine/types.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
field: FormFieldDefinition;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FormFieldDefinition } from '../../annotation/engine/types.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
field: FormFieldDefinition;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="kviewer-form-signature"
|
|
4
|
+
:class="{ 'kviewer-form-signature--filled': hasSigned }"
|
|
5
|
+
@click="onClickSign"
|
|
6
|
+
>
|
|
7
|
+
<img
|
|
8
|
+
v-if="signatureUrl"
|
|
9
|
+
:src="signatureUrl"
|
|
10
|
+
class="kviewer-form-signature__preview"
|
|
11
|
+
alt="Signature"
|
|
12
|
+
>
|
|
13
|
+
<span v-else class="kviewer-form-signature__placeholder">
|
|
14
|
+
Click to sign
|
|
15
|
+
</span>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script setup>
|
|
20
|
+
import { computed } from "vue";
|
|
21
|
+
import { useFormFields } from "../../composables/useFormFields";
|
|
22
|
+
import { useViewerState } from "../../composables/useViewerState";
|
|
23
|
+
const props = defineProps({
|
|
24
|
+
field: { type: Object, required: true }
|
|
25
|
+
});
|
|
26
|
+
const formFields = useFormFields();
|
|
27
|
+
const state = useViewerState();
|
|
28
|
+
const signatureUrl = computed(() => {
|
|
29
|
+
const fv = formFields.getFieldValue(props.field.id);
|
|
30
|
+
if (!fv || typeof fv.value !== "string" || fv.value === "") return null;
|
|
31
|
+
return fv.value;
|
|
32
|
+
});
|
|
33
|
+
const hasSigned = computed(() => !!signatureUrl.value);
|
|
34
|
+
async function onClickSign() {
|
|
35
|
+
if (props.field.readOnly) return;
|
|
36
|
+
if (state.signatures.value.length > 0) {
|
|
37
|
+
const sig = state.signatures.value[0];
|
|
38
|
+
if (sig) {
|
|
39
|
+
formFields.setFieldValue(props.field.id, sig.imageUrl);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (state.signatureHandlers) {
|
|
44
|
+
await state.loadSignatures();
|
|
45
|
+
if (state.signatures.value.length > 0) {
|
|
46
|
+
const sig = state.signatures.value[0];
|
|
47
|
+
if (sig) {
|
|
48
|
+
formFields.setFieldValue(props.field.id, sig.imageUrl);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
</script>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FormFieldDefinition } from '../../annotation/engine/types.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
field: FormFieldDefinition;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FormFieldDefinition } from '../../annotation/engine/types.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
field: FormFieldDefinition;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<textarea
|
|
3
|
+
v-if="props.field.multiLine"
|
|
4
|
+
:value="currentValue"
|
|
5
|
+
:maxlength="props.field.maxLen || void 0"
|
|
6
|
+
:readonly="props.field.readOnly"
|
|
7
|
+
:required="props.field.required"
|
|
8
|
+
:style="fieldStyle"
|
|
9
|
+
class="kviewer-form-input"
|
|
10
|
+
@input="onInput"
|
|
11
|
+
/>
|
|
12
|
+
<input
|
|
13
|
+
v-else
|
|
14
|
+
:type="props.field.password ? 'password' : 'text'"
|
|
15
|
+
:value="currentValue"
|
|
16
|
+
:maxlength="props.field.maxLen || void 0"
|
|
17
|
+
:readonly="props.field.readOnly"
|
|
18
|
+
:required="props.field.required"
|
|
19
|
+
:style="fieldStyle"
|
|
20
|
+
class="kviewer-form-input"
|
|
21
|
+
@input="onInput"
|
|
22
|
+
>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup>
|
|
26
|
+
import { computed } from "vue";
|
|
27
|
+
import { useFormFields } from "../../composables/useFormFields";
|
|
28
|
+
const props = defineProps({
|
|
29
|
+
field: { type: Object, required: true }
|
|
30
|
+
});
|
|
31
|
+
const formFields = useFormFields();
|
|
32
|
+
const currentValue = computed(() => {
|
|
33
|
+
const fv = formFields.getFieldValue(props.field.id);
|
|
34
|
+
return typeof fv?.value === "string" ? fv.value : "";
|
|
35
|
+
});
|
|
36
|
+
const fieldStyle = computed(() => {
|
|
37
|
+
const style = {};
|
|
38
|
+
if (props.field.fontSize && props.field.fontSize > 0) {
|
|
39
|
+
style.fontSize = `${props.field.fontSize}px`;
|
|
40
|
+
} else {
|
|
41
|
+
style.fontSize = "inherit";
|
|
42
|
+
}
|
|
43
|
+
if (props.field.color && props.field.color.length >= 3) {
|
|
44
|
+
style.color = `rgb(${props.field.color[0]}, ${props.field.color[1]}, ${props.field.color[2]})`;
|
|
45
|
+
}
|
|
46
|
+
if (props.field.backgroundColor && props.field.backgroundColor.length >= 3) {
|
|
47
|
+
style.backgroundColor = `rgb(${props.field.backgroundColor[0]}, ${props.field.backgroundColor[1]}, ${props.field.backgroundColor[2]})`;
|
|
48
|
+
}
|
|
49
|
+
const alignMap = { 0: "left", 1: "center", 2: "right" };
|
|
50
|
+
if (props.field.textAlignment != null) {
|
|
51
|
+
style.textAlign = alignMap[props.field.textAlignment] ?? "left";
|
|
52
|
+
}
|
|
53
|
+
if (props.field.comb && props.field.maxLen && props.field.maxLen > 0) {
|
|
54
|
+
const rect = props.field.rect;
|
|
55
|
+
const fieldWidth = rect[2] - rect[0];
|
|
56
|
+
const cellWidth = fieldWidth / props.field.maxLen;
|
|
57
|
+
style.letterSpacing = `${cellWidth - (props.field.fontSize ?? 12) * 0.6}px`;
|
|
58
|
+
style.fontFamily = "monospace";
|
|
59
|
+
}
|
|
60
|
+
return style;
|
|
61
|
+
});
|
|
62
|
+
function onInput(event) {
|
|
63
|
+
const target = event.target;
|
|
64
|
+
formFields.setFieldValue(props.field.id, target.value);
|
|
65
|
+
}
|
|
66
|
+
</script>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FormFieldDefinition } from '../../annotation/engine/types.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
field: FormFieldDefinition;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open: boolean;
|
|
3
|
+
defaultColor: string;
|
|
4
|
+
defaultFontSize: number;
|
|
5
|
+
initialText?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
8
|
+
cancel: () => any;
|
|
9
|
+
submit: (result: {
|
|
10
|
+
inputValue: string;
|
|
11
|
+
color: string;
|
|
12
|
+
fontSize: number;
|
|
13
|
+
}) => any;
|
|
14
|
+
"update:open": (value: boolean) => any;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
16
|
+
onCancel?: (() => any) | undefined;
|
|
17
|
+
onSubmit?: ((result: {
|
|
18
|
+
inputValue: string;
|
|
19
|
+
color: string;
|
|
20
|
+
fontSize: number;
|
|
21
|
+
}) => any) | undefined;
|
|
22
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
23
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const _default: typeof __VLS_export;
|
|
25
|
+
export default _default;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<UModal
|
|
3
|
+
v-model:open="isOpen"
|
|
4
|
+
:title="props.initialText !== void 0 ? 'Edit Text' : 'Free Text'"
|
|
5
|
+
:ui="{ width: 'sm:max-w-md' }"
|
|
6
|
+
>
|
|
7
|
+
<template #body>
|
|
8
|
+
<div class="flex flex-col gap-3">
|
|
9
|
+
<UTextarea
|
|
10
|
+
v-model="inputValue"
|
|
11
|
+
placeholder="Start typing..."
|
|
12
|
+
:rows="3"
|
|
13
|
+
autofocus
|
|
14
|
+
/>
|
|
15
|
+
<div class="flex items-center justify-between">
|
|
16
|
+
<div class="flex gap-1">
|
|
17
|
+
<button
|
|
18
|
+
v-for="c in colors"
|
|
19
|
+
:key="c"
|
|
20
|
+
class="w-6 h-6 rounded-full border-2 cursor-pointer"
|
|
21
|
+
:class="
|
|
22
|
+
c === currentColor ? 'border-white ring-2 ring-blue-500' : 'border-transparent'
|
|
23
|
+
"
|
|
24
|
+
:style="{ backgroundColor: c }"
|
|
25
|
+
@click="currentColor = c"
|
|
26
|
+
/>
|
|
27
|
+
</div>
|
|
28
|
+
<USelect
|
|
29
|
+
v-model="currentFontSize"
|
|
30
|
+
:items="fontSizeItems"
|
|
31
|
+
class="w-20"
|
|
32
|
+
size="sm"
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</template>
|
|
37
|
+
<template #footer>
|
|
38
|
+
<div class="flex justify-end gap-2 w-full">
|
|
39
|
+
<UButton variant="ghost" color="neutral" @click="cancel">
|
|
40
|
+
Cancel
|
|
41
|
+
</UButton>
|
|
42
|
+
<UButton :disabled="!inputValue.trim()" @click="submit">OK</UButton>
|
|
43
|
+
</div>
|
|
44
|
+
</template>
|
|
45
|
+
</UModal>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<script setup>
|
|
49
|
+
import { ref, watch } from "vue";
|
|
50
|
+
import { defaultOptions } from "../../annotation/engine/config";
|
|
51
|
+
const props = defineProps({
|
|
52
|
+
open: { type: Boolean, required: true },
|
|
53
|
+
defaultColor: { type: String, required: true },
|
|
54
|
+
defaultFontSize: { type: Number, required: true },
|
|
55
|
+
initialText: { type: String, required: false }
|
|
56
|
+
});
|
|
57
|
+
const emit = defineEmits(["update:open", "submit", "cancel"]);
|
|
58
|
+
const isOpen = ref(props.open);
|
|
59
|
+
watch(
|
|
60
|
+
() => props.open,
|
|
61
|
+
(v) => {
|
|
62
|
+
isOpen.value = v;
|
|
63
|
+
if (v) {
|
|
64
|
+
inputValue.value = props.initialText ?? "";
|
|
65
|
+
currentColor.value = props.defaultColor;
|
|
66
|
+
currentFontSize.value = String(props.defaultFontSize);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
watch(isOpen, (v) => emit("update:open", v));
|
|
71
|
+
const inputValue = ref("");
|
|
72
|
+
const currentColor = ref(props.defaultColor);
|
|
73
|
+
const currentFontSize = ref(String(props.defaultFontSize));
|
|
74
|
+
const colors = defaultOptions.colors;
|
|
75
|
+
const fontSizeItems = defaultOptions.fontSize.map((s) => ({
|
|
76
|
+
label: `${s}px`,
|
|
77
|
+
value: String(s)
|
|
78
|
+
}));
|
|
79
|
+
function submit() {
|
|
80
|
+
emit("submit", {
|
|
81
|
+
inputValue: inputValue.value,
|
|
82
|
+
color: currentColor.value,
|
|
83
|
+
fontSize: Number(currentFontSize.value)
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function cancel() {
|
|
87
|
+
emit("cancel");
|
|
88
|
+
}
|
|
89
|
+
</script>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open: boolean;
|
|
3
|
+
defaultColor: string;
|
|
4
|
+
defaultFontSize: number;
|
|
5
|
+
initialText?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
8
|
+
cancel: () => any;
|
|
9
|
+
submit: (result: {
|
|
10
|
+
inputValue: string;
|
|
11
|
+
color: string;
|
|
12
|
+
fontSize: number;
|
|
13
|
+
}) => any;
|
|
14
|
+
"update:open": (value: boolean) => any;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
16
|
+
onCancel?: (() => any) | undefined;
|
|
17
|
+
onSubmit?: ((result: {
|
|
18
|
+
inputValue: string;
|
|
19
|
+
color: string;
|
|
20
|
+
fontSize: number;
|
|
21
|
+
}) => any) | undefined;
|
|
22
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
23
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const _default: typeof __VLS_export;
|
|
25
|
+
export default _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open: boolean;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
cancel: () => any;
|
|
6
|
+
submit: (imageUrl: string) => any;
|
|
7
|
+
"update:open": (value: boolean) => any;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
9
|
+
onCancel?: (() => any) | undefined;
|
|
10
|
+
onSubmit?: ((imageUrl: string) => any) | undefined;
|
|
11
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
declare const _default: typeof __VLS_export;
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<UModal v-model:open="isOpen" title="Draw Signature" :ui="{ content: 'sm:max-w-lg' }">
|
|
3
|
+
<template #body>
|
|
4
|
+
<div class="flex flex-col gap-3">
|
|
5
|
+
<div
|
|
6
|
+
class="border border-default rounded bg-white relative"
|
|
7
|
+
:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"
|
|
8
|
+
>
|
|
9
|
+
<canvas
|
|
10
|
+
ref="canvasRef"
|
|
11
|
+
:width="canvasWidth"
|
|
12
|
+
:height="canvasHeight"
|
|
13
|
+
class="cursor-crosshair"
|
|
14
|
+
@pointerdown="onPointerDown"
|
|
15
|
+
@pointermove="onPointerMove"
|
|
16
|
+
@pointerup="onPointerUp"
|
|
17
|
+
@pointerleave="onPointerUp"
|
|
18
|
+
/>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="flex items-center gap-3">
|
|
21
|
+
<div class="flex gap-1">
|
|
22
|
+
<button
|
|
23
|
+
v-for="c in signatureColors"
|
|
24
|
+
:key="c"
|
|
25
|
+
class="w-6 h-6 rounded-full border-2 cursor-pointer"
|
|
26
|
+
:class="
|
|
27
|
+
c === strokeColor ? 'border-white ring-2 ring-blue-500' : 'border-transparent'
|
|
28
|
+
"
|
|
29
|
+
:style="{ backgroundColor: c }"
|
|
30
|
+
@click="strokeColor = c"
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
33
|
+
<UButton variant="ghost" color="neutral" size="xs" @click="clearCanvas">
|
|
34
|
+
Clear
|
|
35
|
+
</UButton>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
<template #footer>
|
|
40
|
+
<div class="flex justify-end gap-2">
|
|
41
|
+
<UButton variant="ghost" color="neutral" @click="cancel">
|
|
42
|
+
Cancel
|
|
43
|
+
</UButton>
|
|
44
|
+
<UButton :disabled="!hasDrawn" @click="submit">
|
|
45
|
+
Save
|
|
46
|
+
</UButton>
|
|
47
|
+
</div>
|
|
48
|
+
</template>
|
|
49
|
+
</UModal>
|
|
50
|
+
</template>
|
|
51
|
+
|
|
52
|
+
<script setup>
|
|
53
|
+
import { ref, watch, nextTick } from "vue";
|
|
54
|
+
import { defaultOptions } from "../../annotation/engine/config";
|
|
55
|
+
const props = defineProps({
|
|
56
|
+
open: { type: Boolean, required: true }
|
|
57
|
+
});
|
|
58
|
+
const emit = defineEmits(["update:open", "submit", "cancel"]);
|
|
59
|
+
const isOpen = ref(props.open);
|
|
60
|
+
watch(
|
|
61
|
+
() => props.open,
|
|
62
|
+
async (v) => {
|
|
63
|
+
isOpen.value = v;
|
|
64
|
+
if (v) {
|
|
65
|
+
hasDrawn.value = false;
|
|
66
|
+
await nextTick();
|
|
67
|
+
clearCanvas();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
watch(isOpen, (v) => emit("update:open", v));
|
|
72
|
+
const canvasWidth = defaultOptions.signature.WIDTH;
|
|
73
|
+
const canvasHeight = defaultOptions.signature.HEIGHT;
|
|
74
|
+
const signatureColors = defaultOptions.signature.COLORS;
|
|
75
|
+
const canvasRef = ref(null);
|
|
76
|
+
const strokeColor = ref(signatureColors[0]);
|
|
77
|
+
const hasDrawn = ref(false);
|
|
78
|
+
let isDrawing = false;
|
|
79
|
+
function getCtx() {
|
|
80
|
+
return canvasRef.value?.getContext("2d") ?? null;
|
|
81
|
+
}
|
|
82
|
+
function onPointerDown(e) {
|
|
83
|
+
isDrawing = true;
|
|
84
|
+
hasDrawn.value = true;
|
|
85
|
+
const ctx = getCtx();
|
|
86
|
+
if (!ctx) return;
|
|
87
|
+
e.target.setPointerCapture(e.pointerId);
|
|
88
|
+
ctx.strokeStyle = strokeColor.value;
|
|
89
|
+
ctx.lineWidth = 2;
|
|
90
|
+
ctx.lineCap = "round";
|
|
91
|
+
ctx.lineJoin = "round";
|
|
92
|
+
ctx.beginPath();
|
|
93
|
+
ctx.moveTo(e.offsetX, e.offsetY);
|
|
94
|
+
}
|
|
95
|
+
function onPointerMove(e) {
|
|
96
|
+
if (!isDrawing) return;
|
|
97
|
+
const ctx = getCtx();
|
|
98
|
+
if (!ctx) return;
|
|
99
|
+
ctx.lineTo(e.offsetX, e.offsetY);
|
|
100
|
+
ctx.stroke();
|
|
101
|
+
}
|
|
102
|
+
function onPointerUp() {
|
|
103
|
+
isDrawing = false;
|
|
104
|
+
}
|
|
105
|
+
function clearCanvas() {
|
|
106
|
+
const ctx = getCtx();
|
|
107
|
+
if (!ctx) return;
|
|
108
|
+
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
109
|
+
hasDrawn.value = false;
|
|
110
|
+
}
|
|
111
|
+
function submit() {
|
|
112
|
+
const canvas = canvasRef.value;
|
|
113
|
+
if (!canvas) return;
|
|
114
|
+
const imageUrl = canvas.toDataURL("image/png");
|
|
115
|
+
emit("submit", imageUrl);
|
|
116
|
+
}
|
|
117
|
+
function cancel() {
|
|
118
|
+
emit("cancel");
|
|
119
|
+
}
|
|
120
|
+
</script>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open: boolean;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
cancel: () => any;
|
|
6
|
+
submit: (imageUrl: string) => any;
|
|
7
|
+
"update:open": (value: boolean) => any;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
9
|
+
onCancel?: (() => any) | undefined;
|
|
10
|
+
onSubmit?: ((imageUrl: string) => any) | undefined;
|
|
11
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
declare const _default: typeof __VLS_export;
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<UPopover>
|
|
3
|
+
<button
|
|
4
|
+
class="relative flex items-center justify-center w-8 h-8 rounded-md transition-colors cursor-pointer"
|
|
5
|
+
:class="isActive ? 'bg-default text-highlighted' : 'text-muted hover:bg-default/50 hover:text-highlighted'"
|
|
6
|
+
title="Signature"
|
|
7
|
+
>
|
|
8
|
+
<UIcon name="i-lucide-pen-tool" class="text-lg" />
|
|
9
|
+
</button>
|
|
10
|
+
<template #content>
|
|
11
|
+
<div class="p-3 min-w-56">
|
|
12
|
+
<!-- Saved signatures -->
|
|
13
|
+
<div v-if="state.signatures.value.length > 0" class="flex flex-col gap-1 mb-2">
|
|
14
|
+
<div
|
|
15
|
+
v-for="sig in state.signatures.value"
|
|
16
|
+
:key="sig.id"
|
|
17
|
+
class="flex items-center gap-2 p-2 rounded hover:bg-elevated cursor-pointer group"
|
|
18
|
+
:class="{ 'ring-1 ring-primary bg-elevated/50': state.activeSignature.value?.id === sig.id }"
|
|
19
|
+
@click="selectSignature(sig)"
|
|
20
|
+
>
|
|
21
|
+
<img
|
|
22
|
+
:src="sig.imageUrl"
|
|
23
|
+
:alt="sig.name || 'Signature'"
|
|
24
|
+
class="h-8 max-w-36 object-contain bg-white rounded border border-default px-2"
|
|
25
|
+
>
|
|
26
|
+
<UButton
|
|
27
|
+
icon="i-lucide-trash-2"
|
|
28
|
+
variant="ghost"
|
|
29
|
+
color="error"
|
|
30
|
+
size="xs"
|
|
31
|
+
class="ml-auto opacity-0 group-hover:opacity-100"
|
|
32
|
+
@click.stop="onDelete(sig.id)"
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<p v-else class="text-xs text-muted mb-2">
|
|
37
|
+
No saved signatures
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
<UButton
|
|
41
|
+
icon="i-lucide-plus"
|
|
42
|
+
variant="outline"
|
|
43
|
+
color="neutral"
|
|
44
|
+
size="xs"
|
|
45
|
+
block
|
|
46
|
+
@click="drawModalOpen = true"
|
|
47
|
+
>
|
|
48
|
+
Add signature
|
|
49
|
+
</UButton>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
</UPopover>
|
|
53
|
+
|
|
54
|
+
<ClientOnly>
|
|
55
|
+
<SignatureDrawModal
|
|
56
|
+
v-model:open="drawModalOpen"
|
|
57
|
+
@submit="onDrawSubmit"
|
|
58
|
+
@cancel="drawModalOpen = false"
|
|
59
|
+
/>
|
|
60
|
+
</ClientOnly>
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
<script setup>
|
|
64
|
+
import { ref, computed } from "vue";
|
|
65
|
+
import { useViewerState } from "../../composables/useViewerState";
|
|
66
|
+
import { AnnotationType } from "../../annotation/engine/types";
|
|
67
|
+
import SignatureDrawModal from "../modals/SignatureDrawModal.vue";
|
|
68
|
+
const state = useViewerState();
|
|
69
|
+
const drawModalOpen = ref(false);
|
|
70
|
+
const isActive = computed(() => state.activeTool.value === AnnotationType.SIGNATURE);
|
|
71
|
+
function selectSignature(sig) {
|
|
72
|
+
state.activeSignature.value = sig;
|
|
73
|
+
state.selectTool(AnnotationType.SIGNATURE, sig.imageUrl);
|
|
74
|
+
}
|
|
75
|
+
async function onDrawSubmit(imageUrl) {
|
|
76
|
+
drawModalOpen.value = false;
|
|
77
|
+
const saved = await state.saveSignature(imageUrl);
|
|
78
|
+
if (saved) {
|
|
79
|
+
selectSignature(saved);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function onDelete(id) {
|
|
83
|
+
await state.deleteSignature(id);
|
|
84
|
+
}
|
|
85
|
+
</script>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|