Skip to content

Commit

Permalink
Mixed fixes - from mh's and blake's feedbacks (#509)
Browse files Browse the repository at this point in the history
* Add base label, add required label, fix searchbar icon position, fix wording 'how to deploy, make required fields

* make stuff rounder

* Revert Canarytoken setting title, center radio input

* fix padding on required

* add label arrow, fix tests

* remove focus from selected card
  • Loading branch information
vittoriaThinkst authored and mclmax committed Jul 16, 2024
1 parent f920627 commit 7d8eb77
Show file tree
Hide file tree
Showing 40 changed files with 303 additions and 111 deletions.
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

0 comments on commit 7d8eb77

Please sign in to comment.