mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-15 11:42:15 +01:00
move ui and api to seperate packages and add npm actions for them
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { ref } from 'vue';
|
||||
import type { CreateClientBody } from '@/utils/api';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import type { CreateClientBody } from '@/packages/api/src';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { ref } from 'vue';
|
||||
import type { Client, UpdateClientBody } from '@/utils/api';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import type { Client, UpdateClientBody } from '@/packages/api/src';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { PencilSquareIcon, TrashIcon } from '@heroicons/vue/20/solid';
|
||||
import type { Client } from '@/utils/api';
|
||||
import type { Client } from '@/packages/api/src';
|
||||
import { canDeleteClients, canUpdateClients } from '@/utils/permissions';
|
||||
import MoreOptionsDropdown from '@/Components/MoreOptionsDropdown.vue';
|
||||
import MoreOptionsDropdown from '@/packages/ui/src/MoreOptionsDropdown.vue';
|
||||
|
||||
const emit = defineEmits<{
|
||||
delete: [];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import MultiselectDropdown from '@/Components/Common/MultiselectDropdown.vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import type { Client } from '@/utils/api';
|
||||
import type { Client } from '@/packages/api/src';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
|
||||
const clientsStore = useClientsStore();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { UserCircleIcon } from '@heroicons/vue/24/solid';
|
||||
import { PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import { ref } from 'vue';
|
||||
import { type Component, ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
import ClientTableRow from '@/Components/Common/Client/ClientTableRow.vue';
|
||||
@@ -36,7 +36,7 @@ const createClient = ref(false);
|
||||
<SecondaryButton
|
||||
v-if="canCreateClients()"
|
||||
@click="createClient = true"
|
||||
:icon="PlusIcon"
|
||||
:icon="PlusIcon as Component"
|
||||
>Create your First Client
|
||||
</SecondaryButton>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { Client } from '@/utils/api';
|
||||
import type { Client } from '@/packages/api/src';
|
||||
import { computed, ref } from 'vue';
|
||||
import { CheckCircleIcon } from '@heroicons/vue/20/solid';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { TrashIcon, ArrowPathIcon } from '@heroicons/vue/20/solid';
|
||||
import MoreOptionsDropdown from '@/Components/MoreOptionsDropdown.vue';
|
||||
import MoreOptionsDropdown from '@/packages/ui/src/MoreOptionsDropdown.vue';
|
||||
const emit = defineEmits<{
|
||||
delete: [];
|
||||
resend: [];
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import type { Invitation } from '@/utils/api';
|
||||
import type { Invitation } from '@/packages/api/src';
|
||||
import TableRow from '@/Components/TableRow.vue';
|
||||
import { capitalizeFirstLetter } from '../../../utils/format';
|
||||
import InvitationMoreOptionsDropdown from '@/Components/Common/Invitation/InvitationMoreOptionsDropdown.vue';
|
||||
import { api } from '@/utils/api';
|
||||
import { api } from '@/packages/api/src';
|
||||
import { getCurrentOrganizationId } from '@/utils/useUser';
|
||||
import { useNotificationsStore } from '@/utils/notification';
|
||||
import { useInvitationsStore } from '@/utils/useInvitations';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { formatCents } from '../../../utils/money';
|
||||
import BillableRateModal from '@/Components/Common/BillableRateModal.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
import BillableRateModal from '@/packages/ui/src/BillableRateModal.vue';
|
||||
import { formatCents } from '@/packages/ui/src/utils/money';
|
||||
|
||||
const show = defineModel('show', { default: false });
|
||||
const saving = defineModel('saving', { default: false });
|
||||
@@ -25,7 +26,10 @@ defineEmits<{
|
||||
The billable rate of {{ memberName }} will be updated to
|
||||
<strong>{{
|
||||
newBillableRate
|
||||
? formatCents(newBillableRate)
|
||||
? formatCents(
|
||||
newBillableRate,
|
||||
getOrganizationCurrencyString()
|
||||
)
|
||||
: ' the default rate of the organization'
|
||||
}}</strong
|
||||
>.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import SelectDropdown from '@/Components/Common/SelectDropdown.vue';
|
||||
import Badge from '@/Components/Common/Badge.vue';
|
||||
import SelectDropdown from '@/packages/ui/src/Input/SelectDropdown.vue';
|
||||
import Badge from '@/packages/ui/src/Badge.vue';
|
||||
import { ChevronDownIcon } from '@heroicons/vue/20/solid';
|
||||
import type { BillableKey } from '@/types/projects';
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import ClientDropdownItem from '@/Components/Common/Client/ClientDropdownItem.vue';
|
||||
import ClientDropdownItem from '@/packages/ui/src/Client/ClientDropdownItem.vue';
|
||||
import { useMembersStore } from '@/utils/useMembers';
|
||||
import { UserIcon, XMarkIcon } from '@heroicons/vue/24/solid';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import type { ProjectMember } from '@/utils/api';
|
||||
import Dropdown from '@/Components/Dropdown.vue';
|
||||
import type { ProjectMember } from '@/packages/api/src';
|
||||
import Dropdown from '@/packages/ui/src/Input/Dropdown.vue';
|
||||
|
||||
const membersStore = useMembersStore();
|
||||
const { members } = storeToRefs(membersStore);
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import type { Member, UpdateMemberBody } from '@/utils/api';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
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 '@/Components/Common/BillableRateInput.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import BillableRateInput from '@/packages/ui/src/Input/BillableRateInput.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import MemberBillableRateModal from '@/Components/Common/Member/MemberBillableRateModal.vue';
|
||||
import MemberBillableSelect from '@/Components/Common/Member/MemberBillableSelect.vue';
|
||||
import { onMounted, watch } from 'vue';
|
||||
import MemberRoleSelect from '@/Components/Common/Member/MemberRoleSelect.vue';
|
||||
import MemberOwnershipTransferConfirmModal from '@/Components/Common/Member/MemberOwnershipTransferConfirmModal.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
|
||||
const { updateMember } = useMembersStore();
|
||||
const show = defineModel('show', { default: false });
|
||||
@@ -154,6 +155,7 @@ const roleDescription = computed(() => {
|
||||
<BillableRateInput
|
||||
focus
|
||||
class="w-full"
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
@keydown.enter="saveWithChecks()"
|
||||
name="memberBillableRate"
|
||||
v-model="
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { ref } from 'vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import type { Role } from '@/types/jetstream';
|
||||
import { Link, useForm } from '@inertiajs/vue3';
|
||||
import { getCurrentOrganizationId } from '@/utils/useUser';
|
||||
@@ -14,8 +14,8 @@ import { filterRoles } from '@/utils/roles';
|
||||
import { hasActiveSubscription, isBillingActivated } from '@/utils/billing';
|
||||
import { CreditCardIcon, UserGroupIcon } from '@heroicons/vue/20/solid';
|
||||
import { canUpdateOrganization } from '@/utils/permissions';
|
||||
import { api } from '@/utils/api';
|
||||
import type { MemberRole } from '@/utils/api';
|
||||
import { api } from '@/packages/api/src';
|
||||
import type { MemberRole } from '@/packages/api/src';
|
||||
import { z } from 'zod';
|
||||
import { useNotificationsStore } from '@/utils/notification';
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { TrashIcon, PencilSquareIcon } from '@heroicons/vue/20/solid';
|
||||
import type { Member } from '@/utils/api';
|
||||
import type { Member } from '@/packages/api/src';
|
||||
import { canDeleteMembers, canUpdateMembers } from '@/utils/permissions';
|
||||
import MoreOptionsDropdown from '@/Components/MoreOptionsDropdown.vue';
|
||||
import MoreOptionsDropdown from '@/packages/ui/src/MoreOptionsDropdown.vue';
|
||||
|
||||
const emit = defineEmits<{
|
||||
delete: [];
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import MultiselectDropdown from '@/Components/Common/MultiselectDropdown.vue';
|
||||
import { useMembersStore } from '@/utils/useMembers';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import type { Member } from '@/utils/api';
|
||||
import type { Member } from '@/packages/api/src';
|
||||
|
||||
const membersStore = useMembersStore();
|
||||
const { members } = storeToRefs(membersStore);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
|
||||
const show = defineModel('show', { default: false });
|
||||
const saving = defineModel('saving', { default: false });
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import SelectDropdown from '@/Components/Common/SelectDropdown.vue';
|
||||
import Badge from '@/Components/Common/Badge.vue';
|
||||
import SelectDropdown from '@/packages/ui/src/Input/SelectDropdown.vue';
|
||||
import Badge from '@/packages/ui/src/Badge.vue';
|
||||
import { ChevronDownIcon } from '@heroicons/vue/20/solid';
|
||||
import type { Role } from '@/types/jetstream';
|
||||
import { usePage } from '@inertiajs/vue3';
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import type { Member } from '@/utils/api';
|
||||
import type { Member } from '@/packages/api/src';
|
||||
import { CheckCircleIcon, UserCircleIcon } from '@heroicons/vue/20/solid';
|
||||
import MemberMoreOptionsDropdown from '@/Components/Common/Member/MemberMoreOptionsDropdown.vue';
|
||||
import TableRow from '@/Components/TableRow.vue';
|
||||
import { capitalizeFirstLetter } from '../../../utils/format';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import { api } from '@/utils/api';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { api } from '@/packages/api/src';
|
||||
import { getCurrentOrganizationId } from '@/utils/useUser';
|
||||
import { useNotificationsStore } from '@/utils/notification';
|
||||
import { canInvitePlaceholderMembers } from '@/utils/permissions';
|
||||
import { useMembersStore } from '@/utils/useMembers';
|
||||
import { ref } from 'vue';
|
||||
import MemberEditModal from '@/Components/Common/Member/MemberEditModal.vue';
|
||||
import { formatCents } from '../../../utils/money';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
import { formatCents } from '@/packages/ui/src/utils/money';
|
||||
|
||||
const props = defineProps<{
|
||||
member: Member;
|
||||
@@ -62,7 +63,12 @@ async function invitePlaceholder(id: string) {
|
||||
</div>
|
||||
<div class="whitespace-nowrap px-3 py-4 text-sm text-muted">
|
||||
{{
|
||||
member.billable_rate ? formatCents(member.billable_rate) : '--'
|
||||
member.billable_rate
|
||||
? formatCents(
|
||||
member.billable_rate,
|
||||
getOrganizationCurrencyString()
|
||||
)
|
||||
: '--'
|
||||
}}
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts" generic="T">
|
||||
import Dropdown from '@/Components/Dropdown.vue';
|
||||
import Dropdown from '@/packages/ui/src/Input/Dropdown.vue';
|
||||
import { type Component, computed, nextTick, ref, watch } from 'vue';
|
||||
import MultiselectDropdownItem from '@/Components/Common/MultiselectDropdownItem.vue';
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { formatCents } from '../../../utils/money';
|
||||
import BillableRateModal from '@/Components/Common/BillableRateModal.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
import BillableRateModal from '@/packages/ui/src/BillableRateModal.vue';
|
||||
import { formatCents } from '@/packages/ui/src/utils/money';
|
||||
|
||||
const show = defineModel('show', { default: false });
|
||||
const saving = defineModel('saving', { default: false });
|
||||
@@ -23,7 +24,12 @@ defineEmits<{
|
||||
<p class="py-0.5 text-center">
|
||||
The organization billable rate will be updated to
|
||||
<strong>{{
|
||||
newBillableRate ? formatCents(newBillableRate) : ' none.'
|
||||
newBillableRate
|
||||
? formatCents(
|
||||
newBillableRate,
|
||||
getOrganizationCurrencyString()
|
||||
)
|
||||
: ' none.'
|
||||
}}</strong
|
||||
>.
|
||||
</p>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import ProjectBadge from '@/Components/Common/Project/ProjectBadge.vue';
|
||||
import ProjectBadge from '@/packages/ui/src/Project/ProjectBadge.vue';
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import Dropdown from '@/Components/Dropdown.vue';
|
||||
import Dropdown from '@/packages/ui/src/Input/Dropdown.vue';
|
||||
import {
|
||||
ComboboxAnchor,
|
||||
ComboboxContent,
|
||||
@@ -12,12 +12,12 @@ import {
|
||||
ComboboxViewport,
|
||||
} from 'radix-vue';
|
||||
import { PlusCircleIcon } from '@heroicons/vue/20/solid';
|
||||
import ProjectDropdownItem from '@/Components/Common/Project/ProjectDropdownItem.vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { api } from '@/utils/api';
|
||||
import { api } from '@/packages/api/src';
|
||||
import { usePage } from '@inertiajs/vue3';
|
||||
import { getRandomColor } from '@/utils/color';
|
||||
import type { Project } from '@/utils/api';
|
||||
import { getRandomColor } from '@/packages/ui/src/utils/color';
|
||||
import type { Project } from '@/packages/api/src';
|
||||
import ProjectDropdownItem from '@/packages/ui/src/Project/ProjectDropdownItem.vue';
|
||||
|
||||
const searchValue = ref('');
|
||||
const searchInput = ref<HTMLElement | null>(null);
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import type { CreateClientBody, CreateProjectBody, Project } from '@/utils/api';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import type {
|
||||
CreateClientBody,
|
||||
CreateProjectBody,
|
||||
Project,
|
||||
} from '@/packages/api/src';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import ClientDropdown from '@/Components/Common/Client/ClientDropdown.vue';
|
||||
import Badge from '@/Components/Common/Badge.vue';
|
||||
import ClientDropdown from '@/packages/ui/src/Client/ClientDropdown.vue';
|
||||
import Badge from '@/packages/ui/src/Badge.vue';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import ProjectColorSelector from '@/Components/Common/Project/ProjectColorSelector.vue';
|
||||
import ProjectEditBillableSection from '@/Components/Common/Project/ProjectEditBillableSection.vue';
|
||||
import ProjectColorSelector from '@/packages/ui/src/Project/ProjectColorSelector.vue';
|
||||
import { UserCircleIcon } from '@heroicons/vue/20/solid';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import ProjectBillableRateModal from '@/Components/Common/Project/ProjectBillableRateModal.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import ProjectBillableRateModal from '@/packages/ui/src/Project/ProjectBillableRateModal.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
import ProjectEditBillableSection from '@/packages/ui/src/Project/ProjectEditBillableSection.vue';
|
||||
|
||||
const { updateProject } = useProjectsStore();
|
||||
const { clients } = storeToRefs(useClientsStore());
|
||||
@@ -124,6 +129,7 @@ async function submitBillableRate() {
|
||||
</div>
|
||||
<ProjectEditBillableSection
|
||||
@submit="submit"
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
v-model:isBillable="project.is_billable"
|
||||
v-model:billableRate="
|
||||
project.billable_rate
|
||||
@@ -143,6 +149,7 @@ async function submitBillableRate() {
|
||||
</DialogModal>
|
||||
<ProjectBillableRateModal
|
||||
v-model:show="showBillableRateModal"
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
@submit="submitBillableRate"
|
||||
:new-billable-rate="project.billable_rate"
|
||||
:project-name="project.name"></ProjectBillableRateModal>
|
||||
|
||||
@@ -4,9 +4,9 @@ import {
|
||||
PencilSquareIcon,
|
||||
ArchiveBoxIcon,
|
||||
} from '@heroicons/vue/20/solid';
|
||||
import type { Project } from '@/utils/api';
|
||||
import type { Project } from '@/packages/api/src';
|
||||
import { canDeleteProjects, canUpdateProjects } from '@/utils/permissions';
|
||||
import MoreOptionsDropdown from '@/Components/MoreOptionsDropdown.vue';
|
||||
import MoreOptionsDropdown from '@/packages/ui/src/MoreOptionsDropdown.vue';
|
||||
const emit = defineEmits<{
|
||||
delete: [];
|
||||
edit: [];
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import MultiselectDropdown from '@/Components/Common/MultiselectDropdown.vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import type { Project } from '@/utils/api';
|
||||
import type { Project } from '@/packages/api/src';
|
||||
|
||||
const projectsStore = useProjectsStore();
|
||||
const { projects } = storeToRefs(projectsStore);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { FolderPlusIcon } from '@heroicons/vue/24/solid';
|
||||
import { PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import { ref } from 'vue';
|
||||
import ProjectCreateModal from '@/Components/Common/Project/ProjectCreateModal.vue';
|
||||
import ProjectCreateModal from '@/packages/ui/src/Project/ProjectCreateModal.vue';
|
||||
import ProjectTableHeading from '@/Components/Common/Project/ProjectTableHeading.vue';
|
||||
import ProjectTableRow from '@/Components/Common/Project/ProjectTableRow.vue';
|
||||
import { canCreateProjects } from '@/utils/permissions';
|
||||
@@ -12,10 +12,11 @@ import type {
|
||||
Project,
|
||||
Client,
|
||||
CreateClientBody,
|
||||
} from '@/utils/api';
|
||||
} from '@/packages/api/src';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
|
||||
defineProps<{
|
||||
projects: Project[];
|
||||
@@ -40,6 +41,7 @@ const { clients } = storeToRefs(useClientsStore());
|
||||
<ProjectCreateModal
|
||||
:createProject
|
||||
:createClient
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
:clients="clients"
|
||||
v-model:show="showCreateProjectModal"></ProjectCreateModal>
|
||||
<div class="flow-root max-w-[100vw] overflow-x-auto">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import ProjectMoreOptionsDropdown from '@/Components/Common/Project/ProjectMoreOptionsDropdown.vue';
|
||||
import type { Project } from '@/utils/api';
|
||||
import type { Project } from '@/packages/api/src';
|
||||
import { computed, ref } from 'vue';
|
||||
import { CheckCircleIcon } from '@heroicons/vue/20/solid';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
@@ -9,7 +9,8 @@ import { useTasksStore } from '@/utils/useTasks';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import TableRow from '@/Components/TableRow.vue';
|
||||
import ProjectEditModal from '@/Components/Common/Project/ProjectEditModal.vue';
|
||||
import { formatCents } from '@/utils/money';
|
||||
import { formatCents } from '@/packages/ui/src/utils/money';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
|
||||
const { clients } = storeToRefs(useClientsStore());
|
||||
const { tasks } = storeToRefs(useTasksStore());
|
||||
@@ -43,7 +44,10 @@ function archiveProject() {
|
||||
const billableRateInfo = computed(() => {
|
||||
if (props.project.is_billable) {
|
||||
if (props.project.billable_rate) {
|
||||
return formatCents(props.project.billable_rate);
|
||||
return formatCents(
|
||||
props.project.billable_rate,
|
||||
getOrganizationCurrencyString()
|
||||
);
|
||||
} else {
|
||||
return 'Default Rate';
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { formatCents } from '../../../utils/money';
|
||||
import BillableRateModal from '@/Components/Common/BillableRateModal.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
import BillableRateModal from '@/packages/ui/src/BillableRateModal.vue';
|
||||
import { formatCents } from '@/packages/ui/src/utils/money';
|
||||
|
||||
const show = defineModel('show', { default: false });
|
||||
const saving = defineModel('saving', { default: false });
|
||||
@@ -25,7 +26,10 @@ defineEmits<{
|
||||
The billable rate of {{ memberName }} will be updated to
|
||||
<strong>{{
|
||||
newBillableRate
|
||||
? formatCents(newBillableRate)
|
||||
? formatCents(
|
||||
newBillableRate,
|
||||
getOrganizationCurrencyString()
|
||||
)
|
||||
: ' the default rate of the project'
|
||||
}}</strong
|
||||
>.
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { ref } from 'vue';
|
||||
import type { CreateProjectMemberBody, ProjectMember } from '@/utils/api';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import type {
|
||||
CreateProjectMemberBody,
|
||||
ProjectMember,
|
||||
} from '@/packages/api/src';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import { useProjectMembersStore } from '@/utils/useProjectMembers';
|
||||
import MemberCombobox from '@/Components/Common/Member/MemberCombobox.vue';
|
||||
import BillableRateInput from '@/Components/Common/BillableRateInput.vue';
|
||||
import BillableRateInput from '@/packages/ui/src/Input/BillableRateInput.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
const { createProjectMember } = useProjectMembersStore();
|
||||
const show = defineModel('show', { default: false });
|
||||
const saving = ref(false);
|
||||
@@ -54,6 +58,7 @@ useFocus(projectNameInput, { initialValue: true });
|
||||
<div class="col-span-3 sm:col-span-1 flex-1">
|
||||
<BillableRateInput
|
||||
name="billable_rate"
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
v-model="
|
||||
projectMember.billable_rate
|
||||
"></BillableRateInput>
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import type { ProjectMember, UpdateProjectMemberBody } from '@/utils/api';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import type {
|
||||
ProjectMember,
|
||||
UpdateProjectMemberBody,
|
||||
} from '@/packages/api/src';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import { useProjectMembersStore } from '@/utils/useProjectMembers';
|
||||
import BillableRateInput from '@/Components/Common/BillableRateInput.vue';
|
||||
import BillableRateInput from '@/packages/ui/src/Input/BillableRateInput.vue';
|
||||
import { UserIcon } from '@heroicons/vue/24/solid';
|
||||
import ProjectMemberBillableRateModal from '@/Components/Common/ProjectMember/ProjectMemberBillableRateModal.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
const { updateProjectMember } = useProjectMembersStore();
|
||||
|
||||
const show = defineModel('show', { default: false });
|
||||
@@ -87,6 +91,7 @@ useFocus(projectNameInput, { initialValue: true });
|
||||
value="Billable Rate"></InputLabel>
|
||||
<BillableRateInput
|
||||
@keydown.enter="submit"
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
name="billable_rate"
|
||||
v-model="
|
||||
projectMemberBody.billable_rate
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { TrashIcon, PencilSquareIcon } from '@heroicons/vue/20/solid';
|
||||
import type { ProjectMember } from '@/utils/api';
|
||||
import type { ProjectMember } from '@/packages/api/src';
|
||||
import { useMembersStore } from '@/utils/useMembers';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed } from 'vue';
|
||||
import MoreOptionsDropdown from '@/Components/MoreOptionsDropdown.vue';
|
||||
import MoreOptionsDropdown from '@/packages/ui/src/MoreOptionsDropdown.vue';
|
||||
|
||||
const emit = defineEmits<{
|
||||
delete: [];
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import { ref } from 'vue';
|
||||
import ProjectMemberTableRow from '@/Components/Common/ProjectMember/ProjectMemberTableRow.vue';
|
||||
import { UserGroupIcon } from '@heroicons/vue/24/solid';
|
||||
import ProjectMemberTableHeading from '@/Components/Common/ProjectMember/ProjectMemberTableHeading.vue';
|
||||
import ProjectMemberCreateModal from '@/Components/Common/ProjectMember/ProjectMemberCreateModal.vue';
|
||||
import type { ProjectMember } from '@/utils/api';
|
||||
import type { ProjectMember } from '@/packages/api/src';
|
||||
|
||||
defineProps<{
|
||||
projectId: string;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import type { ProjectMember } from '@/utils/api';
|
||||
import type { ProjectMember } from '@/packages/api/src';
|
||||
import { computed, ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import TableRow from '@/Components/TableRow.vue';
|
||||
import { useMembersStore } from '@/utils/useMembers';
|
||||
import { useProjectMembersStore } from '@/utils/useProjectMembers';
|
||||
import ProjectMemberMoreOptionsDropdown from '@/Components/Common/ProjectMember/ProjectMemberMoreOptionsDropdown.vue';
|
||||
import { formatCents } from '@/utils/money';
|
||||
import { formatCents } from '@/packages/ui/src/utils/money';
|
||||
import { capitalizeFirstLetter } from '@/utils/format';
|
||||
import ProjectMemberEditModal from '@/Components/Common/ProjectMember/ProjectMemberEditModal.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
|
||||
const props = defineProps<{
|
||||
projectMember: ProjectMember;
|
||||
@@ -48,7 +49,10 @@ const showEditModal = ref(false);
|
||||
<div class="whitespace-nowrap px-3 py-4 text-sm text-muted">
|
||||
{{
|
||||
projectMember.billable_rate
|
||||
? formatCents(projectMember.billable_rate)
|
||||
? formatCents(
|
||||
projectMember.billable_rate,
|
||||
getOrganizationCurrencyString()
|
||||
)
|
||||
: '--'
|
||||
}}
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
formatDate,
|
||||
formatHumanReadableDuration,
|
||||
formatWeek,
|
||||
} from '@/utils/time';
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { BarChart } from 'echarts/charts';
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
} from 'echarts/components';
|
||||
import type { AggregatedTimeEntries } from '@/utils/api';
|
||||
import type { AggregatedTimeEntries } from '@/packages/api/src';
|
||||
import { useCssVar } from '@vueuse/core';
|
||||
|
||||
use([
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import Badge from '@/Components/Common/Badge.vue';
|
||||
import Badge from '@/packages/ui/src/Badge.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
icon: Component;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import SelectDropdown from '@/Components/Common/SelectDropdown.vue';
|
||||
import Badge from '@/Components/Common/Badge.vue';
|
||||
import SelectDropdown from '@/packages/ui/src/Input/SelectDropdown.vue';
|
||||
import Badge from '@/packages/ui/src/Badge.vue';
|
||||
import { type Component, computed } from 'vue';
|
||||
|
||||
const model = defineModel<string | null>({ default: null });
|
||||
|
||||
@@ -11,9 +11,9 @@ import {
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
} from 'echarts/components';
|
||||
import { formatHumanReadableDuration } from '@/utils/time';
|
||||
import { getRandomColorWithSeed } from '@/utils/color';
|
||||
import type { GroupedDataEntries } from '@/utils/api';
|
||||
import { formatHumanReadableDuration } from '@/packages/ui/src/utils/time';
|
||||
import { getRandomColorWithSeed } from '@/packages/ui/src/utils/color';
|
||||
import type { GroupedDataEntries } from '@/packages/api/src';
|
||||
import { useReportingStore } from '@/utils/useReporting';
|
||||
|
||||
use([
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { formatHumanReadableDuration } from '@/utils/time';
|
||||
import { formatCents } from '@/utils/money';
|
||||
import GroupedItemsCountButton from '@/Components/Common/GroupedItemsCountButton.vue';
|
||||
import { formatHumanReadableDuration } from '@/packages/ui/src/utils/time';
|
||||
import { formatCents } from '@/packages/ui/src/utils/money';
|
||||
import GroupedItemsCountButton from '@/packages/ui/src/GroupedItemsCountButton.vue';
|
||||
import { ref } from 'vue';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { useReportingStore } from '@/utils/useReporting';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
const { getNameForReportingRowEntry } = useReportingStore();
|
||||
|
||||
type AggregatedGroupedData = GroupedData & {
|
||||
@@ -54,7 +55,7 @@ const expanded = ref(false);
|
||||
{{ formatHumanReadableDuration(entry.seconds) }}
|
||||
</div>
|
||||
<div class="justify-end pr-6 flex items-center">
|
||||
{{ formatCents(entry.cost) }}
|
||||
{{ formatCents(entry.cost, getOrganizationCurrencyString()) }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { TrashIcon } from '@heroicons/vue/20/solid';
|
||||
import type { Tag } from '@/utils/api';
|
||||
import MoreOptionsDropdown from '@/Components/MoreOptionsDropdown.vue';
|
||||
import type { Tag } from '@/packages/api/src';
|
||||
import MoreOptionsDropdown from '@/packages/ui/src/MoreOptionsDropdown.vue';
|
||||
|
||||
const emit = defineEmits<{
|
||||
delete: [];
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { FolderPlusIcon } from '@heroicons/vue/24/solid';
|
||||
import { PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import { ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useTagsStore } from '@/utils/useTags';
|
||||
import TagTableRow from '@/Components/Common/Tag/TagTableRow.vue';
|
||||
import TagCreateModal from '@/Components/Common/Tag/TagCreateModal.vue';
|
||||
import TagCreateModal from '@/packages/ui/src/Tag/TagCreateModal.vue';
|
||||
import TagTableHeading from '@/Components/Common/Tag/TagTableHeading.vue';
|
||||
import { canCreateTags } from '@/utils/permissions';
|
||||
import type { Tag } from '@/utils/api';
|
||||
import type { Tag } from '@/packages/api/src';
|
||||
defineProps<{
|
||||
createTag: (name: string) => Promise<Tag | undefined>;
|
||||
}>();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { Tag } from '@/utils/api';
|
||||
import type { Tag } from '@/packages/api/src';
|
||||
import { useTagsStore } from '@/utils/useTags';
|
||||
import TagMoreOptionsDropdown from '@/Components/Common/Tag/TagMoreOptionsDropdown.vue';
|
||||
import TableRow from '@/Components/TableRow.vue';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { ref } from 'vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import { useTasksStore } from '@/utils/useTasks';
|
||||
import ProjectDropdown from '@/Components/Common/Project/ProjectDropdown.vue';
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { ref } from 'vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import { useTasksStore } from '@/utils/useTasks';
|
||||
import type { Task, UpdateTaskBody } from '@/utils/api';
|
||||
import type { Task, UpdateTaskBody } from '@/packages/api/src';
|
||||
|
||||
const { updateTask } = useTasksStore();
|
||||
const show = defineModel('show', { default: false });
|
||||
|
||||
@@ -4,9 +4,9 @@ import {
|
||||
PencilSquareIcon,
|
||||
CheckCircleIcon,
|
||||
} from '@heroicons/vue/20/solid';
|
||||
import type { Task } from '@/utils/api';
|
||||
import type { Task } from '@/packages/api/src';
|
||||
import { canDeleteTasks, canUpdateTasks } from '@/utils/permissions';
|
||||
import MoreOptionsDropdown from '@/Components/MoreOptionsDropdown.vue';
|
||||
import MoreOptionsDropdown from '@/packages/ui/src/MoreOptionsDropdown.vue';
|
||||
const emit = defineEmits<{
|
||||
delete: [];
|
||||
edit: [];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import MultiselectDropdown from '@/Components/Common/MultiselectDropdown.vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import type { Task } from '@/utils/api';
|
||||
import type { Task } from '@/packages/api/src';
|
||||
import { useTasksStore } from '@/utils/useTasks';
|
||||
|
||||
const tasksStore = useTasksStore();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { PlusCircleIcon } from '@heroicons/vue/24/solid';
|
||||
import { PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import { ref } from 'vue';
|
||||
@@ -7,7 +7,7 @@ import TaskTableRow from '@/Components/Common/Task/TaskTableRow.vue';
|
||||
import TaskTableHeading from '@/Components/Common/Task/TaskTableHeading.vue';
|
||||
import TaskCreateModal from '@/Components/Common/Task/TaskCreateModal.vue';
|
||||
import { canCreateTasks } from '@/utils/permissions';
|
||||
import type { Task } from '@/utils/api';
|
||||
import type { Task } from '@/packages/api/src';
|
||||
|
||||
const props = defineProps<{
|
||||
projectId: string;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { Task } from '@/utils/api';
|
||||
import type { Task } from '@/packages/api/src';
|
||||
import { CheckCircleIcon } from '@heroicons/vue/20/solid';
|
||||
import { useTasksStore } from '@/utils/useTasks';
|
||||
import TaskMoreOptionsDropdown from '@/Components/Common/Task/TaskMoreOptionsDropdown.vue';
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { nextTick, ref, watch } from 'vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TimeTrackerTagDropdown from '@/Components/Common/TimeTracker/TimeTrackerTagDropdown.vue';
|
||||
import TimeTrackerProjectTaskDropdown from '@/Components/Common/TimeTracker/TimeTrackerProjectTaskDropdown.vue';
|
||||
import BillableToggleButton from '@/Components/Common/BillableToggleButton.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TimeTrackerTagDropdown from '@/packages/ui/src/TimeTracker/TimeTrackerTagDropdown.vue';
|
||||
import TimeTrackerProjectTaskDropdown from '@/packages/ui/src/TimeTracker/TimeTrackerProjectTaskDropdown.vue';
|
||||
import BillableToggleButton from '@/packages/ui/src/Input/BillableToggleButton.vue';
|
||||
import { getCurrentUserId } from '@/utils/useUser';
|
||||
import { useTimeEntriesStore } from '@/utils/useTimeEntries';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import TimePicker from '@/Components/Common/TimePicker.vue';
|
||||
import DatePicker from '@/Components/Common/DatePicker.vue';
|
||||
import { getDayJsInstance, getLocalizedDayJs } from '@/utils/time';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import DatePicker from '@/packages/ui/src/Input/DatePicker.vue';
|
||||
import {
|
||||
getDayJsInstance,
|
||||
getLocalizedDayJs,
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useTasksStore } from '@/utils/useTasks';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
@@ -22,8 +24,10 @@ import type {
|
||||
CreateProjectBody,
|
||||
Project,
|
||||
Client,
|
||||
} from '@/utils/api';
|
||||
} from '@/packages/api/src';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
import TimePicker from '@/packages/ui/src/Input/TimePicker.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
const projectStore = useProjectsStore();
|
||||
const { projects } = storeToRefs(projectStore);
|
||||
const taskStore = useTasksStore();
|
||||
@@ -126,6 +130,7 @@ async function createTag(tag: string) {
|
||||
:clients
|
||||
:createProject
|
||||
:createClient
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
class="mt-1"
|
||||
size="xlarge"
|
||||
:projects="projects"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import Modal from './Modal.vue';
|
||||
import Modal from '@/packages/ui/src/Modal.vue';
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick } from 'vue';
|
||||
import DialogModal from './DialogModal.vue';
|
||||
import InputError from './InputError.vue';
|
||||
import PrimaryButton from './PrimaryButton.vue';
|
||||
import SecondaryButton from './SecondaryButton.vue';
|
||||
import TextInput from './TextInput.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import axios from 'axios';
|
||||
|
||||
const emit = defineEmits(['confirmed']);
|
||||
|
||||
@@ -3,8 +3,8 @@ import { useCurrentTimeEntryStore } from '@/utils/useCurrentTimeEntry';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { formatHumanReadableDuration } from '@/utils/time';
|
||||
import TimeTrackerStartStop from '@/Components/Common/TimeTrackerStartStop.vue';
|
||||
import { formatHumanReadableDuration } from '@/packages/ui/src/utils/time';
|
||||
import TimeTrackerStartStop from '@/packages/ui/src/TimeTrackerStartStop.vue';
|
||||
import { getCurrentOrganizationId } from '@/utils/useUser';
|
||||
const store = useCurrentTimeEntryStore();
|
||||
const { currentTimeEntry, now, isActive } = storeToRefs(store);
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
formatDate,
|
||||
formatHumanReadableDuration,
|
||||
getDayJsInstance,
|
||||
} from '@/utils/time';
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
import { useCssVar } from '@vueuse/core';
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Component } from 'vue';
|
||||
import CardTitle from '@/Components/Common/CardTitle.vue';
|
||||
import CardTitle from '@/packages/ui/src/CardTitle.vue';
|
||||
|
||||
defineProps<{
|
||||
title: string;
|
||||
|
||||
@@ -9,7 +9,7 @@ defineProps<{
|
||||
import {
|
||||
formatHumanReadableDate,
|
||||
formatHumanReadableDuration,
|
||||
} from '@/utils/time';
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
} from 'echarts/components';
|
||||
import { formatHumanReadableDuration } from '@/utils/time';
|
||||
import { formatHumanReadableDuration } from '@/packages/ui/src/utils/time';
|
||||
|
||||
use([
|
||||
CanvasRenderer,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import RecentlyTrackedTasksCardEntry from '@/Components/Dashboard/RecentlyTrackedTasksCardEntry.vue';
|
||||
import DashboardCard from '@/Components/Dashboard/DashboardCard.vue';
|
||||
import { CheckCircleIcon } from '@heroicons/vue/20/solid';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { PlusCircleIcon } from '@heroicons/vue/24/solid';
|
||||
import { router } from '@inertiajs/vue3';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import ProjectBadge from '@/Components/Common/Project/ProjectBadge.vue';
|
||||
import TimeTrackerStartStop from '@/Components/Common/TimeTrackerStartStop.vue';
|
||||
import ProjectBadge from '@/packages/ui/src/Project/ProjectBadge.vue';
|
||||
import TimeTrackerStartStop from '@/packages/ui/src/TimeTrackerStartStop.vue';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed } from 'vue';
|
||||
|
||||
@@ -3,7 +3,7 @@ import DashboardCard from '@/Components/Dashboard/DashboardCard.vue';
|
||||
import TeamActivityCardEntry from '@/Components/Dashboard/TeamActivityCardEntry.vue';
|
||||
import { UserGroupIcon } from '@heroicons/vue/20/solid';
|
||||
import { router } from '@inertiajs/vue3';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
|
||||
defineProps<{
|
||||
latestTeamActivity: {
|
||||
|
||||
@@ -12,13 +12,14 @@ import VChart, { THEME_KEY } from 'vue-echarts';
|
||||
import { computed, provide, ref } from 'vue';
|
||||
import StatCard from '@/Components/Common/StatCard.vue';
|
||||
import { ClockIcon } from '@heroicons/vue/20/solid';
|
||||
import CardTitle from '@/Components/Common/CardTitle.vue';
|
||||
import CardTitle from '@/packages/ui/src/CardTitle.vue';
|
||||
import LinearGradient from 'zrender/lib/graphic/LinearGradient';
|
||||
import ProjectsChartCard from '@/Components/Dashboard/ProjectsChartCard.vue';
|
||||
import { formatHumanReadableDuration } from '@/utils/time';
|
||||
import { formatCents } from '@/utils/money';
|
||||
import { formatHumanReadableDuration } from '@/packages/ui/src/utils/time';
|
||||
import { formatCents } from '@/packages/ui/src/utils/money';
|
||||
import { getWeekStart } from '@/utils/useUser';
|
||||
import { useCssVar } from '@vueuse/core';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
|
||||
use([
|
||||
CanvasRenderer,
|
||||
@@ -195,7 +196,12 @@ const option = ref({
|
||||
" />
|
||||
<StatCard
|
||||
title="Billable Amount"
|
||||
:value="formatCents(props.totalWeeklyBillableAmount.value)" />
|
||||
:value="
|
||||
formatCents(
|
||||
props.totalWeeklyBillableAmount.value,
|
||||
getOrganizationCurrencyString()
|
||||
)
|
||||
" />
|
||||
<ProjectsChartCard
|
||||
:weekly-project-overview="
|
||||
props.weeklyProjectOverview
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ChevronDownIcon } from '@heroicons/vue/20/solid';
|
||||
import Dropdown from '@/Components/Dropdown.vue';
|
||||
import Dropdown from '@/packages/ui/src/Input/Dropdown.vue';
|
||||
import DropdownLink from '@/Components/DropdownLink.vue';
|
||||
import { usePage } from '@inertiajs/vue3';
|
||||
import type { Organization, User } from '@/types/models';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ClockIcon } from '@heroicons/vue/20/solid';
|
||||
import CardTitle from '@/Components/Common/CardTitle.vue';
|
||||
import CardTitle from '@/packages/ui/src/CardTitle.vue';
|
||||
import { usePage } from '@inertiajs/vue3';
|
||||
import { type User } from '@/types/models';
|
||||
import { computed, onMounted, watch } from 'vue';
|
||||
@@ -15,10 +15,15 @@ import { switchOrganization } from '@/utils/useOrganization';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import { useTasksStore } from '@/utils/useTasks';
|
||||
import { useTagsStore } from '@/utils/useTags';
|
||||
import TimeTrackerControls from '@/Components/Common/TimeTracker/TimeTrackerControls.vue';
|
||||
import type { CreateClientBody, CreateProjectBody, Project } from '@/utils/api';
|
||||
import TimeTrackerRunningInDifferentOrganizationOverlay from '@/Components/Common/TimeTracker/TimeTrackerRunningInDifferentOrganizationOverlay.vue';
|
||||
import TimeTrackerControls from '@/packages/ui/src/TimeTracker/TimeTrackerControls.vue';
|
||||
import type {
|
||||
CreateClientBody,
|
||||
CreateProjectBody,
|
||||
Project,
|
||||
} from '@/packages/api/src';
|
||||
import TimeTrackerRunningInDifferentOrganizationOverlay from '@/packages/ui/src/TimeTracker/TimeTrackerRunningInDifferentOrganizationOverlay.vue';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
|
||||
const page = usePage<{
|
||||
auth: {
|
||||
@@ -108,6 +113,7 @@ const { tags } = storeToRefs(useTagsStore());
|
||||
:projects
|
||||
:createTag
|
||||
:isActive
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
v-model:currentTimeEntry="currentTimeEntry"
|
||||
v-model:liveTimer="now"
|
||||
@startLiveTimer="startLiveTimer"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { router, usePage } from '@inertiajs/vue3';
|
||||
import type { Organization, User } from '@/types/models';
|
||||
import DropdownLink from '@/Components/DropdownLink.vue';
|
||||
import Dropdown from '@/Components/Dropdown.vue';
|
||||
import Dropdown from '@/packages/ui/src/Input/Dropdown.vue';
|
||||
|
||||
const page = usePage<{
|
||||
jetstream: {
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
import { isBillingActivated } from '@/utils/billing';
|
||||
import type { User } from '@/types/models';
|
||||
import { ArrowsRightLeftIcon } from '@heroicons/vue/16/solid';
|
||||
import { fetchToken, isTokenValid } from '@/utils/api';
|
||||
import { fetchToken, isTokenValid } from '@/utils/session';
|
||||
|
||||
defineProps({
|
||||
title: String,
|
||||
|
||||
@@ -3,17 +3,17 @@ import { ref } from 'vue';
|
||||
import { useForm, usePage } from '@inertiajs/vue3';
|
||||
import ActionMessage from '@/Components/ActionMessage.vue';
|
||||
import ActionSection from '@/Components/ActionSection.vue';
|
||||
import Checkbox from '@/Components/Checkbox.vue';
|
||||
import Checkbox from '@/packages/ui/src/Input/Checkbox.vue';
|
||||
import ConfirmationModal from '@/Components/ConfirmationModal.vue';
|
||||
import DangerButton from '@/Components/DangerButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import DangerButton from '@/packages/ui/src/Buttons/DangerButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import SectionBorder from '@/Components/SectionBorder.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import type { Token } from '@/types/jetstream';
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -3,10 +3,10 @@ import { ref } from 'vue';
|
||||
import { Head, useForm } from '@inertiajs/vue3';
|
||||
import AuthenticationCard from '@/Components/AuthenticationCard.vue';
|
||||
import AuthenticationCardLogo from '@/Components/AuthenticationCardLogo.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
|
||||
const form = useForm({
|
||||
password: '',
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import { Head, useForm } from '@inertiajs/vue3';
|
||||
import AuthenticationCard from '@/Components/AuthenticationCard.vue';
|
||||
import AuthenticationCardLogo from '@/Components/AuthenticationCardLogo.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
|
||||
defineProps({
|
||||
status: String,
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import { Head, Link, useForm, usePage } from '@inertiajs/vue3';
|
||||
import AuthenticationCard from '@/Components/AuthenticationCard.vue';
|
||||
import AuthenticationCardLogo from '@/Components/AuthenticationCardLogo.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
|
||||
defineProps({
|
||||
canResetPassword: Boolean,
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
import { Head, Link, useForm, usePage } from '@inertiajs/vue3';
|
||||
import AuthenticationCard from '@/Components/AuthenticationCard.vue';
|
||||
import AuthenticationCardLogo from '@/Components/AuthenticationCardLogo.vue';
|
||||
import Checkbox from '@/Components/Checkbox.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import Checkbox from '@/packages/ui/src/Input/Checkbox.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
|
||||
const form = useForm({
|
||||
name: '',
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import { Head, useForm } from '@inertiajs/vue3';
|
||||
import AuthenticationCard from '@/Components/AuthenticationCard.vue';
|
||||
import AuthenticationCardLogo from '@/Components/AuthenticationCardLogo.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
|
||||
const props = defineProps({
|
||||
email: String,
|
||||
|
||||
@@ -3,10 +3,10 @@ import { nextTick, ref } from 'vue';
|
||||
import { Head, useForm } from '@inertiajs/vue3';
|
||||
import AuthenticationCard from '@/Components/AuthenticationCard.vue';
|
||||
import AuthenticationCardLogo from '@/Components/AuthenticationCardLogo.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
|
||||
const recovery = ref(false);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { computed } from 'vue';
|
||||
import { Head, Link, useForm } from '@inertiajs/vue3';
|
||||
import AuthenticationCard from '@/Components/AuthenticationCard.vue';
|
||||
import AuthenticationCardLogo from '@/Components/AuthenticationCardLogo.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
|
||||
const props = defineProps({
|
||||
status: String,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import MainContainer from '@/Pages/MainContainer.vue';
|
||||
import AppLayout from '@/Layouts/AppLayout.vue';
|
||||
import { PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { UserCircleIcon } from '@heroicons/vue/20/solid';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
|
||||
@@ -3,7 +3,7 @@ import MainContainer from '@/Pages/MainContainer.vue';
|
||||
import AppLayout from '@/Layouts/AppLayout.vue';
|
||||
import { PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import { UserGroupIcon } from '@heroicons/vue/20/solid';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import TabBar from '@/Components/Common/TabBar/TabBar.vue';
|
||||
import TabBarItem from '@/Components/Common/TabBar/TabBarItem.vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
import { ref } from 'vue';
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import ActionSection from '@/Components/ActionSection.vue';
|
||||
import DangerButton from '@/Components/DangerButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import DangerButton from '@/packages/ui/src/Buttons/DangerButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
|
||||
const confirmingUserDeletion = ref(false);
|
||||
const passwordInput = ref<HTMLElement | null>(null);
|
||||
|
||||
@@ -3,11 +3,11 @@ import { ref } from 'vue';
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import ActionMessage from '@/Components/ActionMessage.vue';
|
||||
import ActionSection from '@/Components/ActionSection.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import type { Session } from '@/types/jetstream';
|
||||
|
||||
defineProps<{
|
||||
|
||||
@@ -3,12 +3,12 @@ import { ref, computed, watch } from 'vue';
|
||||
import { router, useForm, usePage } from '@inertiajs/vue3';
|
||||
import ActionSection from '@/Components/ActionSection.vue';
|
||||
import ConfirmsPassword from '@/Components/ConfirmsPassword.vue';
|
||||
import DangerButton from '@/Components/DangerButton.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import DangerButton from '@/packages/ui/src/Buttons/DangerButton.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import axios from 'axios';
|
||||
import type { JetstreamUser } from '@/types/jetstream';
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@ import { ref } from 'vue';
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import ActionMessage from '@/Components/ActionMessage.vue';
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
|
||||
const passwordInput = ref<HTMLElement | null>(null);
|
||||
const currentPasswordInput = ref<HTMLElement | null>(null);
|
||||
|
||||
@@ -3,11 +3,11 @@ import { ref } from 'vue';
|
||||
import { Link, router, useForm, usePage } from '@inertiajs/vue3';
|
||||
import ActionMessage from '@/Components/ActionMessage.vue';
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import type { User } from '@/types/models';
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import MainContainer from '@/Pages/MainContainer.vue';
|
||||
import AppLayout from '@/Layouts/AppLayout.vue';
|
||||
import { FolderIcon, PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import { storeToRefs } from 'pinia';
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
import { Link } from '@inertiajs/vue3';
|
||||
import TaskCreateModal from '@/Components/Common/Task/TaskCreateModal.vue';
|
||||
import TaskTable from '@/Components/Common/Task/TaskTable.vue';
|
||||
import CardTitle from '@/Components/Common/CardTitle.vue';
|
||||
import CardTitle from '@/packages/ui/src/CardTitle.vue';
|
||||
import Card from '@/Components/Common/Card.vue';
|
||||
import ProjectMemberTable from '@/Components/Common/ProjectMember/ProjectMemberTable.vue';
|
||||
import ProjectMemberCreateModal from '@/Components/Common/ProjectMember/ProjectMemberCreateModal.vue';
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
import MainContainer from '@/Pages/MainContainer.vue';
|
||||
import AppLayout from '@/Layouts/AppLayout.vue';
|
||||
import { FolderIcon, PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import ProjectTable from '@/Components/Common/Project/ProjectTable.vue';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import ProjectCreateModal from '@/Components/Common/Project/ProjectCreateModal.vue';
|
||||
import ProjectCreateModal from '@/packages/ui/src/Project/ProjectCreateModal.vue';
|
||||
import PageTitle from '@/Components/Common/PageTitle.vue';
|
||||
import { canCreateProjects } from '@/utils/permissions';
|
||||
import TabBarItem from '@/Components/Common/TabBar/TabBarItem.vue';
|
||||
@@ -18,7 +18,8 @@ import type {
|
||||
Client,
|
||||
CreateProjectBody,
|
||||
Project,
|
||||
} from '@/utils/api';
|
||||
} from '@/packages/api/src';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
|
||||
onMounted(() => {
|
||||
useProjectsStore().fetchProjects();
|
||||
@@ -82,6 +83,7 @@ async function createClient(
|
||||
<ProjectCreateModal
|
||||
:createProject
|
||||
:createClient
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
:clients="clients"
|
||||
@submit="createProject"
|
||||
v-model:show="showCreateProjectModal"></ProjectCreateModal>
|
||||
|
||||
@@ -9,31 +9,32 @@ import {
|
||||
CheckCircleIcon,
|
||||
TagIcon,
|
||||
} from '@heroicons/vue/20/solid';
|
||||
import DateRangePicker from '@/Components/Common/DateRangePicker.vue';
|
||||
import DateRangePicker from '@/packages/ui/src/Input/DateRangePicker.vue';
|
||||
import ReportingChart from '@/Components/Common/Reporting/ReportingChart.vue';
|
||||
import BillableIcon from '@/Components/Common/Icons/BillableIcon.vue';
|
||||
import BillableIcon from '@/packages/ui/src/Icons/BillableIcon.vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import {
|
||||
formatHumanReadableDuration,
|
||||
getDayJsInstance,
|
||||
getLocalizedDayJs,
|
||||
} from '@/utils/time';
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
import { type GroupingOption, useReportingStore } from '@/utils/useReporting';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import TagDropdown from '@/Components/Common/Tag/TagDropdown.vue';
|
||||
import type { AggregatedTimeEntriesQueryParams } from '@/utils/api';
|
||||
import TagDropdown from '@/packages/ui/src/Tag/TagDropdown.vue';
|
||||
import type { AggregatedTimeEntriesQueryParams } from '@/packages/api/src';
|
||||
import ReportingFilterBadge from '@/Components/Common/Reporting/ReportingFilterBadge.vue';
|
||||
import ProjectMultiselectDropdown from '@/Components/Common/Project/ProjectMultiselectDropdown.vue';
|
||||
import MemberMultiselectDropdown from '@/Components/Common/Member/MemberMultiselectDropdown.vue';
|
||||
import TaskMultiselectDropdown from '@/Components/Common/Task/TaskMultiselectDropdown.vue';
|
||||
import SelectDropdown from '@/Components/Common/SelectDropdown.vue';
|
||||
import SelectDropdown from '@/packages/ui/src/Input/SelectDropdown.vue';
|
||||
import ReportingGroupBySelect from '@/Components/Common/Reporting/ReportingGroupBySelect.vue';
|
||||
import ReportingRow from '@/Components/Common/Reporting/ReportingRow.vue';
|
||||
import { formatCents } from '@/utils/money';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
import ReportingPieChart from '@/Components/Common/Reporting/ReportingPieChart.vue';
|
||||
import { getCurrentMembershipId, getCurrentRole } from '@/utils/useUser';
|
||||
import ClientMultiselectDropdown from '@/Components/Common/Client/ClientMultiselectDropdown.vue';
|
||||
import { useTagsStore } from '@/utils/useTags';
|
||||
import { formatCents } from '@/packages/ui/src/utils/money';
|
||||
|
||||
const startDate = ref<string>(
|
||||
getLocalizedDayJs(getDayJsInstance()().format()).subtract(14, 'd').format()
|
||||
@@ -322,7 +323,8 @@ async function createTag(tag: string) {
|
||||
class="justify-end pr-6 flex items-center font-medium">
|
||||
{{
|
||||
formatCents(
|
||||
aggregatedTableTimeEntries.cost
|
||||
aggregatedTableTimeEntries.cost,
|
||||
getOrganizationCurrencyString()
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import MainContainer from '@/Pages/MainContainer.vue';
|
||||
import AppLayout from '@/Layouts/AppLayout.vue';
|
||||
import { TagIcon, PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { ref } from 'vue';
|
||||
import TagTable from '@/Components/Common/Tag/TagTable.vue';
|
||||
import TagCreateModal from '@/Components/Common/Tag/TagCreateModal.vue';
|
||||
import TagCreateModal from '@/packages/ui/src/Tag/TagCreateModal.vue';
|
||||
import PageTitle from '@/Components/Common/PageTitle.vue';
|
||||
import { canCreateTags } from '@/utils/permissions';
|
||||
import { useTagsStore } from '@/utils/useTags';
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { useForm, usePage } from '@inertiajs/vue3';
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import type { User } from '@/types/models';
|
||||
import { initializeStores } from '@/utils/init';
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import { ref } from 'vue';
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import ActionSection from '@/Components/ActionSection.vue';
|
||||
import ConfirmationModal from '@/Components/ConfirmationModal.vue';
|
||||
import DangerButton from '@/Components/DangerButton.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DangerButton from '@/packages/ui/src/Buttons/DangerButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
|
||||
const props = defineProps({
|
||||
team: Object,
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useNotificationsStore } from '@/utils/notification';
|
||||
import { api } from '@/utils/api';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import { api } from '@/packages/api/src';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import { DocumentIcon } from '@heroicons/vue/24/solid';
|
||||
import { getCurrentOrganizationId } from '@/utils/useUser';
|
||||
import type { ImportReport, ImportType } from '@/utils/api';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import type { ImportReport, ImportType } from '@/packages/api/src';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { initializeStores } from '@/utils/init';
|
||||
|
||||
const importTypeOptions = ref<ImportType[]>([]);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import type { UpdateOrganizationBody } from '@/utils/api';
|
||||
import BillableRateInput from '@/Components/Common/BillableRateInput.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import type { UpdateOrganizationBody } from '@/packages/api/src';
|
||||
import BillableRateInput from '@/packages/ui/src/Input/BillableRateInput.vue';
|
||||
import { useOrganizationStore } from '@/utils/useOrganization';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import OrganizationBillableRateModal from '@/Components/Common/Organization/OrganizationBillableRateModal.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
|
||||
const store = useOrganizationStore();
|
||||
const { fetchOrganization, updateOrganization } = store;
|
||||
@@ -58,6 +59,7 @@ async function submit() {
|
||||
value="Organization Billable Rate" />
|
||||
<BillableRateInput
|
||||
v-if="organization"
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
v-model="organizationBody.billable_rate"
|
||||
name="organizationBillableRate"></BillableRateInput>
|
||||
</div>
|
||||
|
||||
@@ -4,15 +4,15 @@ import { router, useForm, usePage } from '@inertiajs/vue3';
|
||||
import ActionMessage from '@/Components/ActionMessage.vue';
|
||||
import ActionSection from '@/Components/ActionSection.vue';
|
||||
import ConfirmationModal from '@/Components/ConfirmationModal.vue';
|
||||
import DangerButton from '@/Components/DangerButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import DangerButton from '@/packages/ui/src/Buttons/DangerButton.vue';
|
||||
import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import SectionBorder from '@/Components/SectionBorder.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import type {
|
||||
Organization,
|
||||
OrganizationInvitation,
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import { Link, useForm } from '@inertiajs/vue3';
|
||||
import ActionMessage from '@/Components/ActionMessage.vue';
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import InputError from '@/packages/ui/src/Input/InputError.vue';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TextInput from '@/packages/ui/src/Input/TextInput.vue';
|
||||
import type { Organization } from '@/types/models';
|
||||
import type { Permissions } from '@/types/jetstream';
|
||||
import { CreditCardIcon } from '@heroicons/vue/20/solid';
|
||||
|
||||
@@ -12,19 +12,20 @@ import type {
|
||||
Project,
|
||||
TimeEntry,
|
||||
Client,
|
||||
} from '@/utils/api';
|
||||
} from '@/packages/api/src';
|
||||
import { useElementVisibility } from '@vueuse/core';
|
||||
import { ClockIcon } from '@heroicons/vue/20/solid';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue';
|
||||
import { PlusIcon } from '@heroicons/vue/16/solid';
|
||||
import TimeEntryCreateModal from '@/Components/Common/TimeEntry/TimeEntryCreateModal.vue';
|
||||
import LoadingSpinner from '@/Components/LoadingSpinner.vue';
|
||||
import LoadingSpinner from '@/packages/ui/src/LoadingSpinner.vue';
|
||||
import { useCurrentTimeEntryStore } from '@/utils/useCurrentTimeEntry';
|
||||
import { useTasksStore } from '@/utils/useTasks';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import TimeEntryGroupedTable from '@/Components/Common/TimeEntry/TimeEntryGroupedTable.vue';
|
||||
import TimeEntryGroupedTable from '@/packages/ui/src/TimeEntry/TimeEntryGroupedTable.vue';
|
||||
import { useTagsStore } from '@/utils/useTags';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
import TimeEntryCreateModal from '@/Components/Common/TimeEntry/TimeEntryCreateModal.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
|
||||
const timeEntriesStore = useTimeEntriesStore();
|
||||
const { timeEntries, allTimeEntriesLoaded } = storeToRefs(timeEntriesStore);
|
||||
@@ -134,6 +135,7 @@ async function createClient(
|
||||
:createTag
|
||||
:projects="projects"
|
||||
:tasks="tasks"
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
:timeEntries="timeEntries"
|
||||
:tags="tags"></TimeEntryGroupedTable>
|
||||
<div v-if="timeEntries.length === 0" class="text-center pt-12">
|
||||
|
||||
5
resources/js/packages/api/.gitignore
vendored
Normal file
5
resources/js/packages/api/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
node_modules
|
||||
dist
|
||||
out
|
||||
.DS_Store
|
||||
*.log*
|
||||
171
resources/js/packages/api/package-lock.json
generated
Normal file
171
resources/js/packages/api/package-lock.json
generated
Normal file
@@ -0,0 +1,171 @@
|
||||
{
|
||||
"name": "@solidtime/api",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@solidtime/api",
|
||||
"version": "0.1.0",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@zodios/core": "^10.9.6",
|
||||
"typescript": "^5.5.4",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "^0.38.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vercel/ncc": {
|
||||
"version": "0.38.1",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.1.tgz",
|
||||
"integrity": "sha512-IBBb+iI2NLu4VQn3Vwldyi2QwaXt5+hTyh58ggAMoCGE6DJmPvwL3KPBWcJl1m9LYPChBLE980Jw+CS4Wokqxw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"ncc": "dist/ncc/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@zodios/core": {
|
||||
"version": "10.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@zodios/core/-/core-10.9.6.tgz",
|
||||
"integrity": "sha512-aH4rOdb3AcezN7ws8vDgBfGboZMk2JGGzEq/DtW65MhnRxyTGRuLJRWVQ/2KxDgWvV2F5oTkAS+5pnjKbl0n+A==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"axios": "^0.x || ^1.0.0",
|
||||
"zod": "^3.x"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
|
||||
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.5.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
|
||||
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.23.8",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
|
||||
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
resources/js/packages/api/package.json
Normal file
31
resources/js/packages/api/package.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "@solidtime/api",
|
||||
"version": "0.0.1",
|
||||
"description": "Package containing the solidtime api client and type declarations",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "npx ncc build src/index.ts",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"keywords": [
|
||||
"solidtime",
|
||||
"timetracker",
|
||||
"timetracking",
|
||||
"api",
|
||||
"client"
|
||||
],
|
||||
"type": "module",
|
||||
"author": "solidtime",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@zodios/core": "^10.9.6",
|
||||
"typescript": "^5.5.4",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "^0.38.1"
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,7 @@ import type {
|
||||
ZodiosBodyByAlias,
|
||||
ZodiosQueryParamsByAlias,
|
||||
} from '@zodios/core';
|
||||
import { createApiClient } from '../../../openapi.json.client';
|
||||
import { router } from '@inertiajs/vue3';
|
||||
import { createApiClient } from './openapi.json.client';
|
||||
|
||||
export type SolidTimeApi = ApiOf<typeof api>;
|
||||
|
||||
@@ -135,17 +134,4 @@ export type MyMemberships = ZodiosResponseByAlias<
|
||||
|
||||
export type MyMembership = MyMemberships[0];
|
||||
|
||||
export async function fetchToken() {
|
||||
return new Promise((resolve) => {
|
||||
router.reload({
|
||||
onFinish: () => {
|
||||
resolve(null);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
export function isTokenValid() {
|
||||
return window.document.cookie.includes('XSRF-TOKEN');
|
||||
}
|
||||
|
||||
export const api = createApiClient('/api', { validate: 'none' });
|
||||
2555
resources/js/packages/api/src/openapi.json.client.ts
Normal file
2555
resources/js/packages/api/src/openapi.json.client.ts
Normal file
File diff suppressed because it is too large
Load Diff
27
resources/js/packages/api/tsconfig.json
Normal file
27
resources/js/packages/api/tsconfig.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"resolveJsonModule": true,
|
||||
"noImplicitThis": true,
|
||||
"strict": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"target": "ESNext",
|
||||
"useDefineForClassFields": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"./dist",
|
||||
"./node_modules",
|
||||
"./__tests__",
|
||||
"./coverage"
|
||||
],
|
||||
}
|
||||
5
resources/js/packages/ui/.gitignore
vendored
Normal file
5
resources/js/packages/ui/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
node_modules
|
||||
dist
|
||||
out
|
||||
.DS_Store
|
||||
*.log*
|
||||
1365
resources/js/packages/ui/package-lock.json
generated
Normal file
1365
resources/js/packages/ui/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
46
resources/js/packages/ui/package.json
Normal file
46
resources/js/packages/ui/package.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "@solidtime/ui",
|
||||
"version": "0.0.1",
|
||||
"description": "Package containing the solidtime ui components",
|
||||
"main": "./dist/solidtime-ui-lib.umd.cjs",
|
||||
"module": "./dist/solidtime-ui-lib.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/solidtime-ui-lib.js",
|
||||
"require": "./dist/solidtime-ui-lib.umd.cjs"
|
||||
},
|
||||
"./style.css": "./dist/style.css"
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build && vue-tsc --emitDeclarationOnly",
|
||||
"types": "vue-tsc ",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"keywords": [
|
||||
"solidtime",
|
||||
"timetracker",
|
||||
"timetracking",
|
||||
"api",
|
||||
"client"
|
||||
],
|
||||
"type": "module",
|
||||
"author": "solidtime",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@floating-ui/vue": "^1.1.4",
|
||||
"tailwind-merge": "^2.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.4.1",
|
||||
"@vitejs/plugin-vue": "^5.1.2",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.4.1",
|
||||
"vue": "^3.4.38",
|
||||
"vue-tsc": "^2.0.29"
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import PrimaryButton from './Buttons/PrimaryButton.vue';
|
||||
import DialogModal from './DialogModal.vue';
|
||||
import SecondaryButton from './Buttons/SecondaryButton.vue';
|
||||
import { ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/solid';
|
||||
|
||||
const show = defineModel('show', { default: false });
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user