mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-06-15 13:32:43 +01:00
add responsive tables and time/client/member/tags index page
This commit is contained in:
@@ -3,7 +3,7 @@ import { PLAYWRIGHT_BASE_URL } from '../playwright/config';
|
||||
|
||||
async function goToOrganizationSettings(page) {
|
||||
await page.goto(PLAYWRIGHT_BASE_URL + '/dashboard');
|
||||
await page.getByTestId('organization_switcher').click();
|
||||
await page.locator('[data-testid="organization_switcher"]:visible').click();
|
||||
await page.getByText('Team Settings').click();
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ test('test that organization name can be updated', async ({ page }) => {
|
||||
await page.getByLabel('Team Name').fill('NEW ORG NAME');
|
||||
await page.getByLabel('Team Name').press('Enter');
|
||||
await page.getByLabel('Team Name').press('Meta+r');
|
||||
await expect(page.getByTestId('organization_switcher')).toContainText(
|
||||
await expect(page.locator('[data-testid="organization_switcher"]:visible')).toContainText(
|
||||
'NEW ORG NAME'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex w-full items-center justify-between pb-4">
|
||||
<div class="flex w-full items-center justify-between pb-2.5 sm:pb-4">
|
||||
<h3
|
||||
class="text-white font-bold text-base flex items-center space-x-2.5">
|
||||
<component
|
||||
|
||||
@@ -16,7 +16,7 @@ const createClient = ref(false);
|
||||
|
||||
<template>
|
||||
<ClientCreateModal v-model:show="createClient"></ClientCreateModal>
|
||||
<div class="flow-root">
|
||||
<div class="flow-root max-w-[100vw] overflow-x-auto">
|
||||
<div class="inline-block min-w-full align-middle">
|
||||
<div
|
||||
data-testid="client_table"
|
||||
|
||||
@@ -5,12 +5,10 @@ import TableHeading from '@/Components/Common/TableHeading.vue';
|
||||
<template>
|
||||
<TableHeading>
|
||||
<div
|
||||
class="py-1.5 pr-3 text-left text-sm font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
class="py-1.5 pr-3 text-left font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
Name
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
Status
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">Status</div>
|
||||
<div class="relative py-1.5 pl-3 pr-4 sm:pr-6 lg:pr-8 3xl:pr-12">
|
||||
<span class="sr-only">Edit</span>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,10 @@ defineProps<{
|
||||
|
||||
<template>
|
||||
<div class="flex items-center space-x-2">
|
||||
<svg class="w-5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg
|
||||
class="w-4 sm:w-5"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none">
|
||||
<path
|
||||
d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035c-.01-.004-.019-.001-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427c-.002-.01-.009-.017-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093c.012.004.023 0 .029-.008l.004-.014l-.034-.614c-.003-.012-.01-.02-.02-.022m-.715.002a.023.023 0 0 0-.027.006l-.006.014l-.034.614c0 .012.007.02.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
|
||||
|
||||
@@ -12,7 +12,7 @@ const createClient = ref(false);
|
||||
|
||||
<template>
|
||||
<ClientCreateModal v-model:show="createClient"></ClientCreateModal>
|
||||
<div class="flow-root">
|
||||
<div class="flow-root max-w-[100vw] overflow-x-auto">
|
||||
<div class="inline-block min-w-full align-middle">
|
||||
<div
|
||||
data-testid="client_table"
|
||||
|
||||
@@ -5,21 +5,15 @@ import TableHeading from '@/Components/Common/TableHeading.vue';
|
||||
<template>
|
||||
<TableHeading>
|
||||
<div
|
||||
class="py-1.5 pr-3 text-left text-sm font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
class="py-1.5 pr-3 text-left font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
Name
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
Email
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
Role
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">Email</div>
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">Role</div>
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">
|
||||
Billable Rate
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
Status
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">Status</div>
|
||||
<div
|
||||
class="relative py-1.5 pl-3 pr-4 sm:pr-6 lg:pr-8 3xl:pr-12 bg-row-heading-background">
|
||||
<span class="sr-only">Edit</span>
|
||||
|
||||
18
resources/js/Components/Common/PageTitle.vue
Normal file
18
resources/js/Components/Common/PageTitle.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import type { Component } from 'vue';
|
||||
|
||||
defineProps<{
|
||||
icon: Component;
|
||||
title: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h3
|
||||
class="text-white font-bold text-sm sm:text-base flex items-center space-x-2 sm:space-x-2.5">
|
||||
<component :is="icon" class="w-5 sm:w-6 text-icon-default"></component>
|
||||
<span> {{ title }} </span>
|
||||
</h3>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -16,7 +16,7 @@ const createProject = ref(false);
|
||||
|
||||
<template>
|
||||
<ProjectCreateModal v-model:show="createProject"></ProjectCreateModal>
|
||||
<div class="flow-root">
|
||||
<div class="flow-root max-w-[100vw] overflow-x-auto">
|
||||
<div class="inline-block min-w-full align-middle">
|
||||
<div
|
||||
data-testid="project_table"
|
||||
|
||||
@@ -5,18 +5,14 @@ import TableHeading from '@/Components/Common/TableHeading.vue';
|
||||
<template>
|
||||
<TableHeading>
|
||||
<div
|
||||
class="py-1.5 pr-3 text-left text-sm font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
class="py-1.5 pr-3 text-left font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
Name
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
Client
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">Client</div>
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">
|
||||
Billable Rate
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
Status
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">Status</div>
|
||||
<div class="relative py-1.5 pl-3 pr-4 sm:pr-6 lg:pr-8 3xl:pr-12">
|
||||
<span class="sr-only">Edit</span>
|
||||
</div>
|
||||
|
||||
@@ -5,15 +5,13 @@ import TableHeading from '@/Components/Common/TableHeading.vue';
|
||||
<template>
|
||||
<TableHeading>
|
||||
<div
|
||||
class="py-1.5 pr-3 text-left text-sm font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
class="py-1.5 pr-3 text-left font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
Name
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">
|
||||
Billable Rate
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
Role
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">Role</div>
|
||||
<div class="relative py-1.5 pl-3 pr-4 sm:pr-6 lg:pr-8 3xl:pr-12">
|
||||
<span class="sr-only">Edit</span>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center space-x-1">
|
||||
<div class="flex items-center space-x-0.5 sm:space-x-1">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -18,7 +18,7 @@ const activeClass = computed(() => {
|
||||
<button
|
||||
:class="
|
||||
twMerge(
|
||||
'rounded-md transition px-3 py-1.5 text-sm font-medium hover:text-white',
|
||||
'rounded-md transition px-2 sm:px-3 py-1 sm:py-1.5 text-xs sm:text-sm font-medium hover:text-white',
|
||||
activeClass
|
||||
)
|
||||
">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="contents [&>*]:border-row-separator [&>*]:border-b [&>*]:border-t [&>*]:bg-row-heading-background">
|
||||
class="contents [&>*]:border-row-separator text-xs sm:text-sm [&>*]:border-b [&>*]:border-t [&>*]:bg-row-heading-background">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -5,7 +5,7 @@ import TableHeading from '@/Components/Common/TableHeading.vue';
|
||||
<template>
|
||||
<TableHeading>
|
||||
<div
|
||||
class="py-1.5 pr-3 text-left text-sm font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
class="py-1.5 pr-3 text-left font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
Name
|
||||
</div>
|
||||
<div class="relative py-1.5 pl-3 pr-4 sm:pr-6 lg:pr-8 3xl:pr-12">
|
||||
|
||||
@@ -5,12 +5,10 @@ import TableHeading from '@/Components/Common/TableHeading.vue';
|
||||
<template>
|
||||
<TableHeading>
|
||||
<div
|
||||
class="py-1.5 pr-3 text-left text-sm font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
class="py-1.5 pr-3 text-left font-semibold text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
|
||||
Task Name
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left text-sm font-semibold text-white">
|
||||
Status
|
||||
</div>
|
||||
<div class="px-3 py-1.5 text-left font-semibold text-white">Status</div>
|
||||
<div class="relative py-1.5 pl-3 pr-4 sm:pr-6 lg:pr-8 3xl:pr-12">
|
||||
<span class="sr-only">Edit</span>
|
||||
</div>
|
||||
|
||||
@@ -82,13 +82,14 @@ function updateProjectAndTask(projectId: string, taskId: string) {
|
||||
class="border-b border-card-border transition"
|
||||
data-testid="time_entry_row">
|
||||
<MainContainer>
|
||||
<div class="flex py-1.5 items-center justify-between group">
|
||||
<div class="sm:flex py-1.5 items-center justify-between group">
|
||||
<div class="flex space-x-1 items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="h-4 w-4 rounded bg-card-background border-input-border text-accent-500/80 focus:ring-accent-500/80" />
|
||||
<TimeEntryDescriptionInput
|
||||
@changed="updateTimeEntryDescription"
|
||||
class="flex-1"
|
||||
:modelValue="
|
||||
timeEntry.description
|
||||
"></TimeEntryDescriptionInput>
|
||||
@@ -105,7 +106,7 @@ function updateProjectAndTask(projectId: string, taskId: string) {
|
||||
<TimeEntryRowTagDropdown
|
||||
@changed="updateTimeEntryTags"
|
||||
:modelValue="timeEntry.tags"></TimeEntryRowTagDropdown>
|
||||
<div>
|
||||
<div class="flex-1">
|
||||
<TimeEntryRangeSelector
|
||||
:start="timeEntry.start"
|
||||
:end="timeEntry.end"
|
||||
@@ -122,7 +123,7 @@ function updateProjectAndTask(projectId: string, taskId: string) {
|
||||
<TimeTrackerStartStop
|
||||
@changed="onStartStopClick"
|
||||
:active="!!(timeEntry.start && !timeEntry.end)"
|
||||
class="opacity-20 group-hover:opacity-100"></TimeTrackerStartStop>
|
||||
class="opacity-20 hidden sm:flex group-hover:opacity-100"></TimeTrackerStartStop>
|
||||
<TimeEntryMoreOptionsDropdown
|
||||
@delete="
|
||||
deleteTimeEntry
|
||||
|
||||
@@ -8,7 +8,7 @@ defineProps<{
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="bg-card-background border-t border-b border-card-border py-1.5 text-sm">
|
||||
class="bg-card-background border-t border-b border-card-border py-1.5 text-xs sm:text-sm">
|
||||
<MainContainer>
|
||||
<DaySectionHeader :date></DaySectionHeader>
|
||||
</MainContainer>
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
<template>
|
||||
<section class="flex flex-col">
|
||||
<h3
|
||||
class="text-white font-bold pb-4 textbase flex items-center space-x-2.5">
|
||||
<component
|
||||
v-if="icon"
|
||||
:is="icon"
|
||||
class="w-6 text-icon-default"></component>
|
||||
<span>{{ title }}</span>
|
||||
</h3>
|
||||
<CardTitle :title="title" :icon="icon"></CardTitle>
|
||||
|
||||
<div
|
||||
class="rounded-lg bg-card-background border border-card-border flex-1 flex items-center">
|
||||
<div class="divide-y divide-card-background-separator w-full">
|
||||
@@ -19,6 +13,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Component } from 'vue';
|
||||
import CardTitle from '@/Components/Common/CardTitle.vue';
|
||||
|
||||
defineProps<{
|
||||
title: string;
|
||||
|
||||
@@ -43,14 +43,15 @@ const switchToTeam = (team: Organization) => {
|
||||
class="flex hover:bg-white/10 cursor-pointer transition px-2 py-1 rounded-lg w-full items-center justify-between font-medium">
|
||||
<div class="flex flex-1 space-x-3 items-center w-4/5">
|
||||
<div
|
||||
class="rounded-lg bg-blue-900 font-semibold flex-shrink-0 text-white w-7 h-7 flex items-center justify-center">
|
||||
class="rounded sm:rounded-lg bg-blue-900 font-semibold text-xs sm:text-base flex-shrink-0 text-white w-5 sm:w-7 h-5 sm:h-7 flex items-center justify-center">
|
||||
{{
|
||||
page.props.auth.user.current_team.name
|
||||
.slice(0, 1)
|
||||
.toUpperCase()
|
||||
}}
|
||||
</div>
|
||||
<span class="text-lg flex-1 truncate font-semibold">
|
||||
<span
|
||||
class="text-sm sm:text-lg flex-1 truncate font-semibold">
|
||||
{{ page.props.auth.user.current_team.name }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -58,7 +59,7 @@ const switchToTeam = (team: Organization) => {
|
||||
<button
|
||||
class="p-1 transition hover:bg-white/10 rounded-full flex items-center w-9 h-9">
|
||||
<ChevronDownIcon
|
||||
class="w-full mt-[1px]"></ChevronDownIcon>
|
||||
class="w-5 sm:w-full mt-[1px]"></ChevronDownIcon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,7 +14,7 @@ withDefaults(
|
||||
<template>
|
||||
<button
|
||||
:type="type"
|
||||
class="inline-flex items-center px-3 py-2 bg-accent-300/10 border border-accent-300/20 rounded-md font-medium text-sm text-white hover:bg-accent-300/20 focus:bg-white active:bg-accent-300/20 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition ease-in-out duration-150">
|
||||
class="inline-flex items-center px-2 sm:px-3 py-1 sm:py-2 bg-accent-300/10 border border-accent-300/20 rounded-md font-medium text-xs sm:text-sm text-white hover:bg-accent-300/20 focus:bg-white active:bg-accent-300/20 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition ease-in-out duration-150">
|
||||
<slot />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
@@ -17,7 +17,7 @@ const props = withDefaults(
|
||||
<template>
|
||||
<button
|
||||
:type="type"
|
||||
class="bg-button-secondary-background border border-button-secondary-border hover:bg-button-secondary-background-hover shadow-sm transition text-white text-sm px-3 py-2 rounded-lg font-semibold inline-flex items-center space-x-1.5 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-25 ease-in-out">
|
||||
class="bg-button-secondary-background border border-button-secondary-border hover:bg-button-secondary-background-hover shadow-sm transition text-white text-xs sm:text-sm px-2 sm:px-3 py-1 sm:py-2 rounded-lg font-semibold inline-flex items-center space-x-1.5 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-25 ease-in-out">
|
||||
<span
|
||||
:class="
|
||||
twMerge('flex items-center ', props.icon ? 'space-x-1.5' : '')
|
||||
@@ -25,7 +25,7 @@ const props = withDefaults(
|
||||
<component
|
||||
v-if="props.icon"
|
||||
:is="props.icon"
|
||||
class="w-5 h-5 -ml-1"></component>
|
||||
class="w-4 sm:w-5 h-4 sm:h-5 -ml-0.5 sm:-ml-1"></component>
|
||||
<span>
|
||||
<slot />
|
||||
</span>
|
||||
|
||||
@@ -166,7 +166,7 @@ function onTimeEntryEnterPress() {
|
||||
type="text" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between pl-2">
|
||||
<div class="flex items-center w-[130px]">
|
||||
<div class="flex items-center w-[130px] sm:w-auto">
|
||||
<TimeTrackerProjectTaskDropdown
|
||||
@changed="updateTimeEntry"
|
||||
v-model:project="currentTimeEntry.project_id"
|
||||
@@ -190,12 +190,12 @@ function onTimeEntryEnterPress() {
|
||||
@blur="updateTimerAndStartLiveTimerUpdate"
|
||||
@keydown.enter="onTimeEntryEnterPress"
|
||||
v-model="currentTime"
|
||||
class="w-[110px] sm:w-[130px] h-full text-white py-2.5 rounded-r-lg text-center px-4 text-lg font-bold bg-card-background border-none placeholder-muted focus:ring-0 transition focus:bg-card-background-active"
|
||||
class="w-[110px] sm:w-[130px] h-full text-white py-2.5 rounded-r-lg text-center px-4 text-sm sm:text-lg font-bold bg-card-background border-none placeholder-muted focus:ring-0 transition focus:bg-card-background-active"
|
||||
type="text" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pl-6 pr-3 absolute sm:relative top-[7px] right-0">
|
||||
<div class="pl-6 pr-3 absolute sm:relative top-[6px] sm:top-0 right-0">
|
||||
<TimeTrackerStartStop
|
||||
:active="isActive"
|
||||
@changed="onToggleButtonPress"
|
||||
|
||||
@@ -128,10 +128,10 @@ onMounted(async () => {
|
||||
</div>
|
||||
<div class="flex-1 sm:ml-[230px] 2xl:ml-[270px]">
|
||||
<div
|
||||
class="sm:hidden w-full px-3 py-3 border-b border-b-default-background-separator text-muted flex justify-between items-center">
|
||||
class="sm:hidden w-full px-3 py-1 border-b border-b-default-background-separator text-muted flex justify-between items-center">
|
||||
<Bars3Icon
|
||||
@click="showSidebarMenu = !showSidebarMenu"
|
||||
class="w-8 text-muted"></Bars3Icon>
|
||||
class="w-7 text-muted"></Bars3Icon>
|
||||
<OrganizationSwitcher></OrganizationSwitcher>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { onMounted, ref } from 'vue';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
import ClientTable from '@/Components/Common/Client/ClientTable.vue';
|
||||
import ClientCreateModal from '@/Components/Common/Client/ClientCreateModal.vue';
|
||||
import PageTitle from '@/Components/Common/PageTitle.vue';
|
||||
|
||||
onMounted(() => {
|
||||
useClientsStore().fetchClients();
|
||||
@@ -23,12 +24,7 @@ const createClient = ref(false);
|
||||
<MainContainer
|
||||
class="py-5 border-b border-default-background-separator flex justify-between items-center">
|
||||
<div class="flex items-center space-x-6">
|
||||
<h3
|
||||
class="text-white font-bold text-base flex items-center space-x-2.5">
|
||||
<UserCircleIcon
|
||||
class="w-6 text-icon-default"></UserCircleIcon>
|
||||
<span> Clients </span>
|
||||
</h3>
|
||||
<PageTitle :icon="UserCircleIcon" title="Clients"> </PageTitle>
|
||||
<TabBar>
|
||||
<TabBarItem>All</TabBarItem>
|
||||
<TabBarItem active>Active</TabBarItem>
|
||||
|
||||
@@ -50,11 +50,11 @@ const props = defineProps<{
|
||||
<template>
|
||||
<AppLayout title="Dashboard" data-testid="dashboard_view">
|
||||
<MainContainer
|
||||
class="pt-8 pb-6 border-b border-default-background-separator">
|
||||
class="pt-5 sm:pt-8 pb-4 sm:pb-6 border-b border-default-background-separator">
|
||||
<TimeTracker></TimeTracker>
|
||||
</MainContainer>
|
||||
<MainContainer
|
||||
class="grid gap-6 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 pt-5 pb-6 border-b border-default-background-separator items-stretch">
|
||||
class="grid gap-5 sm:gap-6 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 pt-3 sm:pt-5 pb-4 sm:pb-6 border-b border-default-background-separator items-stretch">
|
||||
<RecentlyTrackedTasksCard
|
||||
:latestTasks="props.latestTasks"></RecentlyTrackedTasksCard>
|
||||
<LastSevenDaysCard
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div class="px-4 sm:px-6 lg:px-8 3xl:px-12 mx-auto">
|
||||
<div class="px-3 sm:px-6 lg:px-8 3xl:px-12 mx-auto">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ref } from 'vue';
|
||||
import MemberTable from '@/Components/Common/Member/MemberTable.vue';
|
||||
import MemberInviteModal from '@/Components/Common/Member/MemberInviteModal.vue';
|
||||
import type { Role } from '@/types/jetstream';
|
||||
import PageTitle from '@/Components/Common/PageTitle.vue';
|
||||
|
||||
const inviteMember = ref(false);
|
||||
|
||||
@@ -22,13 +23,8 @@ defineProps<{
|
||||
<AppLayout title="Members" data-testid="members_view">
|
||||
<MainContainer
|
||||
class="py-5 border-b border-default-background-separator flex justify-between items-center">
|
||||
<div class="flex items-center space-x-6">
|
||||
<h3
|
||||
class="text-white font-bold text-base flex items-center space-x-2.5">
|
||||
<UserGroupIcon
|
||||
class="w-6 text-icon-default"></UserGroupIcon>
|
||||
<span> Members </span>
|
||||
</h3>
|
||||
<div class="flex items-center space-x-4 sm:space-x-6">
|
||||
<PageTitle :icon="UserGroupIcon" title="Members"> </PageTitle>
|
||||
<TabBar>
|
||||
<TabBarItem active>All</TabBarItem>
|
||||
<TabBarItem>Active</TabBarItem>
|
||||
|
||||
@@ -9,6 +9,7 @@ import ProjectTable from '@/Components/Common/Project/ProjectTable.vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import ProjectCreateModal from '@/Components/Common/Project/ProjectCreateModal.vue';
|
||||
import PageTitle from '@/Components/Common/PageTitle.vue';
|
||||
|
||||
onMounted(() => {
|
||||
useProjectsStore().fetchProjects();
|
||||
@@ -20,13 +21,9 @@ const createProject = ref(false);
|
||||
<template>
|
||||
<AppLayout title="Projects" data-testid="projects_view">
|
||||
<MainContainer
|
||||
class="py-5 border-b border-default-background-separator flex justify-between items-center">
|
||||
<div class="flex items-center space-x-6">
|
||||
<h3
|
||||
class="text-white font-bold text-base flex items-center space-x-2.5">
|
||||
<FolderIcon class="w-6 text-icon-default"></FolderIcon>
|
||||
<span> Projects </span>
|
||||
</h3>
|
||||
class="py-3 sm:py-5 border-b border-default-background-separator flex justify-between items-center">
|
||||
<div class="flex items-center space-x-3 sm:space-x-6">
|
||||
<PageTitle :icon="FolderIcon" title="Projects"> </PageTitle>
|
||||
<TabBar>
|
||||
<TabBarItem>All</TabBarItem>
|
||||
<TabBarItem active>Active</TabBarItem>
|
||||
|
||||
@@ -6,6 +6,7 @@ import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import { ref } from 'vue';
|
||||
import TagTable from '@/Components/Common/Tag/TagTable.vue';
|
||||
import TagCreateModal from '@/Components/Common/Tag/TagCreateModal.vue';
|
||||
import PageTitle from '@/Components/Common/PageTitle.vue';
|
||||
|
||||
const createTag = ref(false);
|
||||
</script>
|
||||
@@ -15,11 +16,7 @@ const createTag = ref(false);
|
||||
<MainContainer
|
||||
class="py-5 border-b border-default-background-separator flex justify-between items-center">
|
||||
<div class="flex items-center space-x-6">
|
||||
<h3
|
||||
class="text-white font-bold text-base flex items-center space-x-2.5">
|
||||
<FolderIcon class="w-6 text-icon-default"></FolderIcon>
|
||||
<span> Tags </span>
|
||||
</h3>
|
||||
<PageTitle :icon="FolderIcon" title="Tags"> </PageTitle>
|
||||
</div>
|
||||
<SecondaryButton :icon="PlusIcon" @click="createTag = true"
|
||||
>Create Tag</SecondaryButton
|
||||
|
||||
@@ -49,7 +49,7 @@ const groupedTimeEntries = computed(() => {
|
||||
<template>
|
||||
<AppLayout title="Dashboard" data-testid="time_view">
|
||||
<MainContainer
|
||||
class="py-8 border-b border-default-background-separator">
|
||||
class="py-4 sm:py-8 border-b border-default-background-separator">
|
||||
<TimeTracker></TimeTracker>
|
||||
</MainContainer>
|
||||
<div v-for="(value, key) in groupedTimeEntries" :key="key">
|
||||
|
||||
Reference in New Issue
Block a user