Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mixed fixes - from mh's and blake's feedbacks #509

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend_vue/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ declare module 'vue' {
BaseFormSelect: typeof import('./src/components/base/BaseFormSelect.vue')['default']
BaseFormTextField: typeof import('./src/components/base/BaseFormTextField.vue')['default']
BaseGenerateTokenSettings: typeof import('./src/components/base/BaseGenerateTokenSettings.vue')['default']
BaseLabel: typeof import('./src/components/base/BaseLabel.vue')['default']
BaseLabelArrow: typeof import('./src/components/base/BaseLabelArrow.vue')['default']
BaseLink: typeof import('./src/components/base/BaseLink.vue')['default']
BaseMessageBox: typeof import('./src/components/base/BaseMessageBox.vue')['default']
BaseModal: typeof import('./src/components/base/BaseModal.vue')['default']
Expand Down
3 changes: 3 additions & 0 deletions frontend_vue/src/assets/icons/label_arrow_1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend_vue/src/assets/icons/label_arrow_2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend_vue/src/components/HistoryToken.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
to show incident info all screen height -->
<div
id="alerts-card-list"
class="flex-col md:p-16 md:bg-grey-50 md:rounded-xl md:overflow-scroll md:max-h-[70svh]"
class="flex-col md:p-16 md:bg-grey-50 md:rounded-3xl md:overflow-scroll md:max-h-[70svh]"
:class="{ 'hidden md:block': selectedAlert }"
>
<!-- TODO: add number of alerts? -->
Expand Down
2 changes: 1 addition & 1 deletion frontend_vue/src/components/ManageToken.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
class="md:mx-32 md:max-w-[50vw] w-full"
>
<div
class="flex flex-col justify-center p-16 md:p-32 rounded-xl bg-grey-50"
class="flex flex-col justify-center p-16 md:p-32 rounded-3xl bg-grey-50"
>
<Suspense>
<component
Expand Down
25 changes: 16 additions & 9 deletions frontend_vue/src/components/ModalContentGenerateToken.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,22 @@
:is-animation="true"
:has-shadow="true"
/>
<Form
ref="generateTokenFormRef"
:validation-schema="schema"
class="flex flex-col w-full md:w-[90%] lg:w-[70%] gap-32 px-8 mt-32 mb-16"
@submit="onSubmit"
@invalid-submit="onInvalidSubmit"
>
<component :is="dynamicForm" />
</Form>
<div class="w-full md:w-[90%] lg:w-[70%] px-8 mt-32 mb-8">
<Form
ref="generateTokenFormRef"
:validation-schema="schema"
class="flex flex-col gap-32"
@submit="onSubmit"
@invalid-submit="onInvalidSubmit"
>
<component :is="dynamicForm" />
</Form>
<div class="w-full mt-16 text-left sm:pl-24">
<p class="text-xs text-grey-400">
<span class="text-green">*</span> Required field
</p>
</div>
</div>
</template>

<script setup lang="ts">
Expand Down
2 changes: 1 addition & 1 deletion frontend_vue/src/components/ModalContentHowToUse.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<li
v-for="item in parsedHowToUseToken"
:key="item.id"
class="grid justify-start grid-flow-col gap-8 px-16 py-8 text-left bg-white border rounded-xl border-grey-200 text-grey-500"
class="grid justify-start grid-flow-col gap-8 px-16 py-8 text-left bg-white border rounded-2xl border-grey-200 text-grey-500"
>
<component
:is="item.component"
Expand Down
2 changes: 1 addition & 1 deletion frontend_vue/src/components/ModalToken.vue
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ const title = computed(() => {
case ModalType.NewToken:
return 'New Token Created!';
case ModalType.HowToUse:
return 'How does it work?';
return 'How does this work?';
default:
return 'Add Token';
}
Expand Down
4 changes: 2 additions & 2 deletions frontend_vue/src/components/base/BaseCodeSnippet.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
>{{ label }}</label
>

<div class="relative bg-white border rounded-lg border-grey-100">
<div class="relative bg-white border rounded-2xl border-grey-100">
<button
v-if="showExpandButton"
id="show-all-button"
Expand All @@ -30,7 +30,7 @@
:id="label"
:code="code"
:lang="lang"
class="min-h-[3.5rem] overflow-scroll rounded-xl"
class="min-h-[3.5rem] overflow-scroll rounded-2xl"
:style="{
height: componentHeight,
}"
Expand Down
53 changes: 16 additions & 37 deletions frontend_vue/src/components/base/BaseFormTextField.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { mount } from '@vue/test-utils';
import BaseFormTextField from '@/components/base/BaseFormTextField.vue';
import BaseLabelArrow from './BaseLabelArrow.vue';
import BaseLabel from './BaseLabel.vue';

describe('BaseTextField.vue', () => {
it('renders label when passed', () => {
Expand All @@ -13,16 +15,6 @@ describe('BaseTextField.vue', () => {
expect(wrapper.text()).toMatch(label);
});

it('shows asterisk when required', () => {
const modelValue = 'initialText';
const id = 'custom id';

const wrapper = mount(BaseFormTextField, {
props: { label: 'Required Field', required: true, modelValue, id },
});
expect(wrapper.html()).toContain('<span class="text-green-500">*</span>');
});

it('switches between input and textarea based on multiline prop', async () => {
const modelValue = 'initialText';
const id = 'custom id';
Expand All @@ -38,33 +30,6 @@ describe('BaseTextField.vue', () => {
expect(wrapper.find('textarea').exists()).toBe(true);
});

// Test has been removed since BaseTextField became a Form Field
// with integrated Form validator handlers
//
// it('emits update:modelValue event on input', async () => {
// const modelValue = 'initialText';
// const id = 'custom id';

// const wrapper = mount(BaseFormTextField, {
// props: { multiline: false, modelValue, label: 'Label', id },
// });
// const inputElement = wrapper.find('input');
// await inputElement.setValue('new value');
// expect(wrapper.emitted()).toHaveProperty('update:modelValue');
// expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['new value']);
// });

// it('displays error message when hasError is true', () => {
// const modelValue = 'initialText';
// const id = 'custom id';
// const errorMessage = 'Error message';

// const wrapper = mount(BaseFormTextField, {
// props: { hasError: true, errorMessage, modelValue, label: 'Label', id },
// });
// expect(wrapper.text()).toContain(errorMessage);
// });

it('displays helper message', () => {
const modelValue = 'initialText';
const id = 'custom id';
Expand All @@ -88,4 +53,18 @@ describe('BaseTextField.vue', () => {
await wrapper.setProps({ disabled: true });
expect(wrapper.find('input').attributes('disabled')).toBeDefined();
});

it('renders BaseLabelArrow when hasArrow is true', () => {
const wrapper = mount(BaseFormTextField, {
props: {
id: 'test-input',
label: 'Test Label',
hasArrow: true,
},
components: { BaseLabelArrow, BaseLabel },
});

expect(wrapper.findComponent(BaseLabelArrow).exists()).toBe(true);
expect(wrapper.findComponent(BaseLabel).exists()).toBe(false);
});
});
34 changes: 22 additions & 12 deletions frontend_vue/src/components/base/BaseFormTextField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,21 @@
class="flex flex-col text-grey-800 textfield-wrapper"
:class="{ 'w-full': fullWidth }"
>
<label
:for="id"
class="mb-4 ml-4 font-semibold"
>{{ label }}
<span
v-if="required"
class="text-green-500"
>*</span
></label
<BaseLabel
v-if="!hasArrow"
:id="id"
:required="required"
>
{{ label }}
</BaseLabel>
<BaseLabelArrow
v-if="hasArrow"
:id="id"
:label="label"
:arrow-variant="arrowVariant"
:arrow-word-position="arrowWordPosition"
:required="required"
/>
<component
:is="inputType"
:id="id"
Expand All @@ -25,7 +30,7 @@
:class="[
{ 'border-red shadow-none': errorMessage },
{ 'border-grey-200 bg-grey-100 shadow-none text-grey-300': disabled },
{ 'hide-scrollbar': multiline }
{ 'hide-scrollbar': multiline },
]"
:style="`height: ${multilineHeight}`"
:placeholder="placeholder"
Expand Down Expand Up @@ -71,6 +76,10 @@ const props = defineProps<{
fullWidth?: boolean;
disabled?: boolean;
value?: string;
hasArrow?: boolean;
arrowVariant?: 'one' | 'two';
// positions the arrow under the word at the given index
arrowWordPosition?: number;
}>();

const inputType = computed(() => (props.multiline ? 'textarea' : 'input'));
Expand All @@ -92,9 +101,10 @@ function validateIfErrorExists(e: Event) {
<style>
.hide-scrollbar {
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Internet Explorer 10+ */
-ms-overflow-style: none; /* Internet Explorer 10+ */
}
.hide-scrollbar::-webkit-scrollbar { /* WebKit */
.hide-scrollbar::-webkit-scrollbar {
/* WebKit */
width: 0;
height: 0;
}
Expand Down
11 changes: 7 additions & 4 deletions frontend_vue/src/components/base/BaseGenerateTokenSettings.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<template>
<div
class="relative border flex-1 group flex flex-col px-16 sm:px-24 pt-16 pb-24 bg-white rounded-xl top-[0px] shadow-solid-shadow-grey border-grey-200"
class="relative border flex-1 group flex flex-col px-16 sm:px-24 pt-16 pb-24 bg-white rounded-3xl top-[0px] shadow-solid-shadow-grey border-grey-200"
>
<h3
v-if="settingType"
class="flex flex-row gap-8 mb-16 text-sm font-semibold text-left text-grey-400"
>
<font-awesome-icon
Expand All @@ -12,6 +13,10 @@
></font-awesome-icon>
{{ settingType }} Settings
</h3>
<span
v-else
class="mb-8"
></span>
<slot></slot>
</div>
</template>
Expand All @@ -20,15 +25,13 @@
import { computed } from 'vue';

const props = defineProps<{
settingType: 'Canarytoken' | 'Notifications';
settingType?: 'Canarytoken';
}>();

const icon = computed(() => {
switch (props.settingType) {
case 'Canarytoken':
return 'gear';
case 'Notifications':
return 'bell';
default:
return 'gear';
}
Expand Down
14 changes: 14 additions & 0 deletions frontend_vue/src/components/base/BaseLabel.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { mount } from '@vue/test-utils';
import BaseLabel from './BaseLabel.vue';

describe('BaseLabel.vue', () => {
it('shows asterisk when required', () => {
const modelValue = 'initialText';
const id = 'custom id';

const wrapper = mount(BaseLabel, {
props: { label: 'Required Field', required: true, modelValue, id },
});
expect(wrapper.html()).toContain('<span class="text-green-500"> *</span>');
});
});
21 changes: 21 additions & 0 deletions frontend_vue/src/components/base/BaseLabel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<label
:for="id"
class="mb-4 ml-4 font-semibold"
>
<slot></slot>
<span
v-if="required"
class="text-green-500"
>
*</span
></label
>
</template>

<script setup lang="ts">
defineProps<{
id: string;
required?: boolean;
}>();
</script>
52 changes: 52 additions & 0 deletions frontend_vue/src/components/base/BaseLabelArrow.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { mount, shallowMount } from '@vue/test-utils';
import { ref } from 'vue';
import BaseFormTextField from '@/components/base/BaseFormTextField.vue';
import BaseLabelArrow from './BaseLabelArrow.vue';
import BaseLabel from './BaseLabel.vue';

describe('BaseLabelArrow.vue', () => {
it('renders label when passed', () => {
const label = 'Test Label';
const modelValue = 'initialText';
const id = 'custom_id';

const wrapper = mount(BaseLabelArrow, {
props: { label, modelValue, id },
});
expect(wrapper.text()).toMatch(label);
});

it('adds arrow class to the specified word in the label', () => {
const arrowWordPosition = 2;
const label = ref('Test Label Here');
const arrowVariant = ref('one');

const wrapper = shallowMount(BaseLabelArrow, {
//@ts-ignore
props: { arrowWordPosition, label, arrowVariant },
});

//@ts-ignore
const labelArrowed = wrapper.vm.labelArrowed;

const expectedOutput =
'Test <span class="label-arrow label-arrow__one" alt="arrow">Label</span> Here';

expect(labelArrowed).toBe(expectedOutput);
});

it('should not add arrow if no position is provided', () => {
const label = ref('Test Label Here');
const arrowVariant = ref('one');

const wrapper = shallowMount(BaseLabelArrow, {
//@ts-ignore
props: { label, arrowVariant },
});

//@ts-ignore
const labelArrowed = wrapper.vm.labelArrowed;

expect(labelArrowed).toBe('Test Label Here');
});
});
Loading