All files / src/components/navigation/annotation AnnotationCreateModal.vue

93.1% Statements 27/29
100% Branches 12/12
84.61% Functions 11/13
92.85% Lines 26/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125      2x                                         11x                               11x             1x   11x         1x                             30x         30x 30x 30x   30x 30x   30x   30x   30x 30x   30x 5x               1x 1x 9x         1x   1x           1x 1x             30x        
<template>
  <v-overlay
    v-bind="$attrs"
    v-model="modelValue"
    persistent
    width="503px"
    :scrim="false"
    location-strategy="connected"
    :target="target"
  >
    <v-card class="position-relative mx-5">
      <v-card-title class="pt-4">
        <span>{{ t('labels.annotationCreate') }}</span>
        <v-btn
          variant="text"
          icon="close"
          color="shark_400"
          data-testid="close-btn"
          @click="cancel"
          class="position-absolute"
          style="top: 0; right: 0"
        />
      </v-card-title>
      <v-card-subtitle>
        <span>{{ t('texts.annotationCreateHelp') }}</span>
      </v-card-subtitle>
      <v-card-text class="pb-1">
        <AnnotationForm
          v-if="proxy"
          v-model="proxy"
        />
      </v-card-text>
      <v-card-actions class="px-6 pb-4">
        <v-spacer />
        <v-btn
          class="px-4 py-2"
          color="minsk_900"
          variant="plain"
          @click="cancel"
        >
          <span>{{ t('labels.cancel') }}</span>
        </v-btn>
        <v-btn
          class="px-4 py-2"
          color="minsk_900"
          variant="flat"
          data-testid="submit-btn"
          @click="create()"
        >
          <span>{{ t('labels.confirm') }}</span>
        </v-btn>
      </v-card-actions>
    </v-card>
  </v-overlay>
  <AnnotationCreateSnackbar v-model="s_annotationCreate" />
</template>
 
<script setup lang="ts">
import { useViewer3cr } from '@/composables/useViewer3cr';
import { computed, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useToolStore } from '@/stores/tool.store';
import { DataOverlayAnnotation } from '@3cr/viewer-types-ts';
 
interface Props {
  annotation?: DataOverlayAnnotation | null;
  returnTo?: string;
}
 
const props = withDefaults(defineProps<Props>(), {
  annotation: null,
  returnTo: '',
});
 
const { t } = useI18n();
const { annotationCreateTool } = useToolStore();
const viewer3cr = useViewer3cr();
 
const proxy = ref<DataOverlayAnnotation>();
const s_annotationCreate = ref<boolean>(false);
 
const modelValue = defineModel<boolean>({ default: false });
 
const target = computed(() => annotationCreateTool.position.value);
 
watch(
  () => props.annotation,
  (value) => {
    if (value) {
      proxy.value = JSON.parse(JSON.stringify(value));
    }
  },
  { immediate: true },
);
 
async function create(): Promise<void> {
  // Nested serialization required for 3CR
  const payload = JSON.parse(JSON.stringify(proxy.value));
  payload.CallToAction.Actions = payload.CallToAction.Actions.map(
    (action: any) => ({
      ActionType: action.ActionType,
      ActionData: JSON.stringify(action.ActionData),
    }),
  );
  payload.CallToAction = JSON.stringify(payload.CallToAction);
 
  await viewer3cr.createAnnotation2dTool({
    message: undefined,
    returnChannel: payload,
    returnTo: props.returnTo,
  });
 
  modelValue.value = false;
  s_annotationCreate.value = true;
}
 
async function cancel(): Promise<void> {
  modelValue.value = false;
}
 
defineExpose({ s_annotationCreate });
 
defineOptions({ inheritAttrs: false });
</script>