mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-16 20:22:15 +01:00
Add Field component system and migrate UI
This commit is contained in:
@@ -14,7 +14,7 @@ import {
|
||||
ComboboxViewport,
|
||||
} from 'radix-vue';
|
||||
import Dropdown from '@/packages/ui/src/Input/Dropdown.vue';
|
||||
import { Button } from '@/Components/ui/button';
|
||||
import { Button } from '@/packages/ui/src/Buttons';
|
||||
|
||||
const { members } = useMembersQuery();
|
||||
|
||||
@@ -77,7 +77,6 @@ function selectMember(member: Member) {
|
||||
:disabled="disabled"
|
||||
type="button"
|
||||
variant="input"
|
||||
size="input"
|
||||
class="w-full justify-between text-start font-normal">
|
||||
<div class="flex items-center gap-3 truncate">
|
||||
<UserIcon class="w-4 text-text-secondary shrink-0" />
|
||||
@@ -92,7 +91,7 @@ function selectMember(member: Member) {
|
||||
<template #content>
|
||||
<ComboboxRoot
|
||||
v-model:search-term="searchValue"
|
||||
:open="open"
|
||||
v-model:open="open"
|
||||
class="relative"
|
||||
:filter-function="(val: string[]) => val">
|
||||
<ComboboxAnchor>
|
||||
|
||||
@@ -9,8 +9,7 @@ import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import Checkbox from '@/packages/ui/src/Input/Checkbox.vue';
|
||||
import { useNotificationsStore } from '@/utils/notification';
|
||||
import { getCurrentOrganizationId } from '@/utils/useUser';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import { Field, FieldLabel, FieldError } from '@/packages/ui/src/field';
|
||||
|
||||
const props = defineProps<{
|
||||
show: boolean;
|
||||
@@ -113,25 +112,21 @@ const close = () => {
|
||||
},
|
||||
}">
|
||||
<template #default="{ field }">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center space-x-3 text-sm">
|
||||
<Checkbox
|
||||
:id="field.name"
|
||||
:name="field.name"
|
||||
:checked="field.state.value"
|
||||
@update:checked="field.handleChange"
|
||||
@blur="field.handleBlur" />
|
||||
<InputLabel
|
||||
:for="field.name"
|
||||
class="font-medium text-text-primary">
|
||||
I understand that this will permanently delete all data
|
||||
related to this member
|
||||
</InputLabel>
|
||||
</div>
|
||||
<InputError
|
||||
class="pl-7 pt-2"
|
||||
:message="field.state.meta.errors[0]" />
|
||||
</div>
|
||||
<Field orientation="horizontal">
|
||||
<Checkbox
|
||||
:id="field.name"
|
||||
:name="field.name"
|
||||
:checked="field.state.value"
|
||||
@update:checked="field.handleChange"
|
||||
@blur="field.handleBlur" />
|
||||
<FieldLabel :for="field.name" class="font-medium text-text-primary">
|
||||
I understand that this will permanently delete all data related
|
||||
to this member
|
||||
</FieldLabel>
|
||||
<FieldError v-if="field.state.meta.errors[0]" class="pl-7 pt-2">
|
||||
{{ field.state.meta.errors[0] }}
|
||||
</FieldError>
|
||||
</Field>
|
||||
</template>
|
||||
</form.Field>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Member, UpdateMemberBody } from '@/packages/api/src';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { type MemberBillableKey, useMembersStore } from '@/utils/useMembers';
|
||||
import BillableRateInput from '@/packages/ui/src/Input/BillableRateInput.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import { Field, FieldLabel } from '@/packages/ui/src/field';
|
||||
import MemberBillableRateModal from '@/Components/Common/Member/MemberBillableRateModal.vue';
|
||||
import MemberBillableSelect from '@/Components/Common/Member/MemberBillableSelect.vue';
|
||||
import { onMounted, watch } from 'vue';
|
||||
@@ -121,28 +121,24 @@ const roleDescription = computed(() => {
|
||||
<template #content>
|
||||
<div class="pb-5 pt-2 divide-y divide-border-secondary">
|
||||
<div class="pb-5 flex space-x-6">
|
||||
<div>
|
||||
<InputLabel for="role" value="Role" />
|
||||
<MemberRoleSelect
|
||||
v-model="memberBody.role"
|
||||
class="mt-2"
|
||||
name="role"></MemberRoleSelect>
|
||||
</div>
|
||||
<Field>
|
||||
<FieldLabel for="role">Role</FieldLabel>
|
||||
<MemberRoleSelect v-model="memberBody.role" name="role"></MemberRoleSelect>
|
||||
</Field>
|
||||
<div class="flex-1 text-xs flex items-center pt-6">
|
||||
<p>{{ roleDescription }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4 pt-5">
|
||||
<div class="col-span-6 sm:col-span-4 flex-1 flex space-x-5">
|
||||
<div>
|
||||
<InputLabel for="billableType" value="Billable" />
|
||||
<Field>
|
||||
<FieldLabel for="billableType">Billable</FieldLabel>
|
||||
<MemberBillableSelect
|
||||
v-model="billableRateSelect"
|
||||
class="mt-2"
|
||||
name="billableType"></MemberBillableSelect>
|
||||
</div>
|
||||
<div v-if="billableRateSelect === 'custom-rate'" class="flex-1">
|
||||
<InputLabel for="memberBillableRate" value="Billable Rate" />
|
||||
</Field>
|
||||
<Field v-if="billableRateSelect === 'custom-rate'" class="flex-1">
|
||||
<FieldLabel for="memberBillableRate">Billable Rate</FieldLabel>
|
||||
<BillableRateInput
|
||||
v-model="memberBody.billable_rate"
|
||||
focus
|
||||
@@ -150,7 +146,7 @@ const roleDescription = computed(() => {
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
name="memberBillableRate"
|
||||
@keydown.enter="saveWithChecks()"></BillableRateInput>
|
||||
</div>
|
||||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,8 +5,7 @@ import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { ref } from 'vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import { Field, FieldLabel, FieldError } from '@/packages/ui/src/field';
|
||||
import type { Role } from '@/types/jetstream';
|
||||
import { Link, useForm } from '@inertiajs/vue3';
|
||||
import { getCurrentOrganizationId } from '@/utils/useUser';
|
||||
@@ -111,8 +110,8 @@ useFocus(clientNameInput, { initialValue: true });
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="space-y-4">
|
||||
<div class="col-span-6 sm:col-span-4 flex-1">
|
||||
<InputLabel for="email" value="Email" />
|
||||
<Field class="col-span-6 sm:col-span-4 flex-1">
|
||||
<FieldLabel for="email">Email</FieldLabel>
|
||||
<TextInput
|
||||
id="email"
|
||||
ref="memberEmailInput"
|
||||
@@ -120,16 +119,16 @@ useFocus(clientNameInput, { initialValue: true });
|
||||
name="email"
|
||||
type="text"
|
||||
placeholder="Member Email"
|
||||
class="mt-1 block w-full"
|
||||
class="block w-full"
|
||||
required
|
||||
autocomplete="memberName"
|
||||
@keydown.enter="submit" />
|
||||
<InputError :message="errors.email" class="mt-2" />
|
||||
</div>
|
||||
<FieldError v-if="errors.email">{{ errors.email }}</FieldError>
|
||||
</Field>
|
||||
|
||||
<div v-if="availableRoles.length > 0">
|
||||
<InputLabel for="roles" value="Role" />
|
||||
<InputError :message="errors.role" class="mt-2" />
|
||||
<Field v-if="availableRoles.length > 0">
|
||||
<FieldLabel for="roles">Role</FieldLabel>
|
||||
<FieldError v-if="errors.role">{{ errors.role }}</FieldError>
|
||||
|
||||
<div
|
||||
class="relative z-0 mt-1 border border-card-border rounded-lg bg-card-background cursor-pointer">
|
||||
@@ -182,7 +181,7 @@ useFocus(clientNameInput, { initialValue: true });
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Field>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
|
||||
Reference in New Issue
Block a user