Skip to content

Commit

Permalink
Decrease print width formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
vanarok committed Aug 3, 2024
1 parent c750e2f commit ea977f9
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 117 deletions.
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"tabWidth": 4,
"useTabs": false,
"singleQuote": true,
"printWidth": 180,
"printWidth": 140,
"semi": false,
"bracketSpacing": false,
"trailingComma": "none",
Expand Down
2 changes: 1 addition & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"recommendations": ["Vue.volar"]
"recommendations": ["Vue.volar"]
}
15 changes: 13 additions & 2 deletions api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@ export const getClients = () => api.get('/clients?per_page=6&page=1?status=activ
export const getProjects = () => api.get('/projects?per_page=6&page=1?&status=active&without_deleted_clients=true&sort=budgeted_hours|desc')
export const getProject = (id: string) => api.get(`/projects/${id}`)

export const getTasks = ({clientId, projectId, taskStatusId, filter}: {clientId?: string; projectId: string | null; taskStatusId?: string; filter?: string}) =>
export const getTasks = ({
clientId,
projectId,
taskStatusId,
filter
}: {
clientId?: string
projectId: string | null
taskStatusId?: string
filter?: string
}) =>
api.get(`/tasks?without_deleted_clients=true&sort=number|desc&per_page=6&page=1&client_status=uninvoiced&status=active`, {
params: {
project_tasks: projectId,
Expand All @@ -41,7 +51,8 @@ export const putTask = (
...(action && {[action]: true})
}
})
export const postTask = ({description, projectId}: {description: string; projectId: string}) => api.post(`/tasks`, {description, project_id: projectId})
export const postTask = ({description, projectId}: {description: string; projectId: string}) =>
api.post(`/tasks`, {description, project_id: projectId})
export const deleteTask = (id: string) => api.delete(`/tasks/${id}`)

export const getTaskStatuses = () => api.get('/task_statuses')
Expand Down
42 changes: 26 additions & 16 deletions components/ProjectsActivator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,43 +19,53 @@
</style>
<template>
<div style="width: 100%; height: 36.25px; box-sizing: border-box; position: relative">
<button style="width:100%; height: 100%" @click="$emit('open-projects-page')">
<button style="width: 100%; height: 100%" @click="$emit('open-projects-page')">
<Transition mode="out-in">
<div v-if="projectId"
style="position: relative; display: flex; align-items: center; justify-items: start">
<div v-if="isPending" class="project-name-skeleton"/>
<div v-if="projectId" style="position: relative; display: flex; align-items: center; justify-items: start">
<div v-if="isPending" class="project-name-skeleton" />
<div v-else-if="isError">Error</div>
<div v-else class="project-name">
{{
project.data.name === '' ? project.data.display_name : project.data.name
}}
{{ project.data.name === '' ? project.data.display_name : project.data.name }}
</div>
</div>

<div v-else>
All projects
</div>
<div v-else>All projects</div>
</Transition>
</button>
<button
style="font-weight: bold; position: absolute; background: #747bff22; color: #747bff; font-size: large; padding: 0.25em 0.5em; right: 0.25em; top: 0.15em; line-height: 1em;"
@click.stop="$emit('clear-project-choose')">
style="
font-weight: bold;
position: absolute;
background: #747bff22;
color: #747bff;
font-size: large;
padding: 0.25em 0.5em;
right: 0.25em;
top: 0.15em;
line-height: 1em;
"
@click.stop="$emit('clear-project-choose')"
>
<div style="transform: rotate(45deg)">+</div>
</button>
</div>
</template>

<script lang="ts" setup>
import {useQuery} from "@tanstack/vue-query";
import {getProject} from "@/api";
import {computed} from "vue";
import {useQuery} from '@tanstack/vue-query'
import {getProject} from '@/api'
import {computed} from 'vue'
const props = defineProps<{
projectId: string | null | undefined
}>()
const enabled = computed(() => props.projectId !== null && props.projectId !== undefined)
const {data: project, isPending, isError} = useQuery({
const {
data: project,
isPending,
isError
} = useQuery({
enabled,
queryKey: ['project', props.projectId],
queryFn: () => getProject(props.projectId)
Expand Down
10 changes: 8 additions & 2 deletions components/Task.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
/>
<div class="info">
<span class="time">{{ getTime() }}</span>
<button v-if="!task.project_id" class="assign-project-button i-mdi-folder-plus-outline" @click="enableAssignProjectMode(task)"></button>
<button
v-if="!task.project_id"
class="assign-project-button i-mdi-folder-plus-outline"
@click="enableAssignProjectMode(task)"
></button>
<button v-if="false" class="i-mdi-content-save-outline save"></button>
<button class="i-mdi-timer-play" :disabled="taskFinished" @click="startTask({task, status: statuses.running})"></button>
<button
Expand Down Expand Up @@ -227,7 +231,9 @@ const getTime = () => {
transform: translate(50%, 50%);
button {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
box-shadow:
0 4px 8px 0 rgba(0, 0, 0, 0.2),
0 6px 20px 0 rgba(0, 0, 0, 0.19);
div {
font-size: 2em;
Expand Down
12 changes: 5 additions & 7 deletions entrypoints/background.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
export default defineBackground(() => {
console.log('Hello background!', { id: browser.runtime.id });
console.log('Hello background!', {id: browser.runtime.id})

// Allows users to open the side panel by clicking on the action toolbar icon
// @ts-expect-error: sidePanel is not typed
browser.sidePanel
.setPanelBehavior({ openPanelOnActionClick: true })
.catch((error: unknown) => console.error(error));
});
// Allows users to open the side panel by clicking on the action toolbar icon
// @ts-expect-error: sidePanel is not typed
browser.sidePanel.setPanelBehavior({openPanelOnActionClick: true}).catch((error: unknown) => console.error(error))
})
17 changes: 14 additions & 3 deletions entrypoints/sidepanel/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,15 @@ if (!isComplete.value) {
<div v-else style="display: flex; flex-direction: column; gap: 1em">
<div class="control-panel">
<Transition mode="out-in">
<div v-if="page === 'tasks'" style="display: flex; flex-direction: column; gap: 1em; width: 100%; align-items: center">
<ProjectsActivator :projectId @open-projects-page="page = 'projects'" @clear-project-choose="updateProjectChoose(null)" />
<div
v-if="page === 'tasks'"
style="display: flex; flex-direction: column; gap: 1em; width: 100%; align-items: center"
>
<ProjectsActivator
:projectId
@open-projects-page="page = 'projects'"
@clear-project-choose="updateProjectChoose(null)"
/>
<div v-if="project" class="values">
<div>
Budget
Expand All @@ -77,7 +84,11 @@ if (!isComplete.value) {
<button v-else-if="assignProjectMode" id="project-choose-activator" @click="cancelAssignProjectMode">
<span>Cancel</span>
</button>
<button v-else-if="page === 'projects' || page === 'settings'" id="project-choose-activator" @click="page = 'tasks'">
<button
v-else-if="page === 'projects' || page === 'settings'"
id="project-choose-activator"
@click="page = 'tasks'"
>
<span>Return to tasks</span>
</button>
</Transition>
Expand Down
102 changes: 49 additions & 53 deletions helpers.ts
Original file line number Diff line number Diff line change
@@ -1,115 +1,111 @@
import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration';
import relativeTime from 'dayjs/plugin/relativeTime';
import dayjs from 'dayjs'
import duration from 'dayjs/plugin/duration'
import relativeTime from 'dayjs/plugin/relativeTime'

export type TimeLogType = [number, number, string, boolean];
export type TimeLogsType = TimeLogType[];
export type TimeLogType = [number, number, string, boolean]
export type TimeLogsType = TimeLogType[]

export function parseTimeLog(log: string) {
if (log === '' || log === '[]') {
return [];
return []
}

const defaultRow: TimeLogsType = [[0, 0, '', true]];
const parsed: TimeLogsType = JSON.parse(log);
const defaultRow: TimeLogsType = [[0, 0, '', true]]
const parsed: TimeLogsType = JSON.parse(log)

if (!parsed.length) {
return defaultRow;
return defaultRow
}

return parsed;
return parsed
}

export function calculateHours(log: string, includeRunning = false) {
const times = parseTimeLog(log);
const times = parseTimeLog(log)

let seconds = 0;
let seconds = 0

for (const [start, finish] of times) {
if (start > finish && !includeRunning) {
continue;
continue
}

const finishTime = finish !== 0 ? finish : Math.floor(Date.now() / 1000);
const durationInSeconds = finishTime - start;
const finishTime = finish !== 0 ? finish : Math.floor(Date.now() / 1000)
const durationInSeconds = finishTime - start

seconds += Math.max(durationInSeconds, 0);
seconds += Math.max(durationInSeconds, 0)
}

const totalHours = Math.floor(seconds / 3600);
const totalMinutes = Math.floor((seconds % 3600) / 60);
const totalSecondsRemaining = seconds % 60;
const totalHours = Math.floor(seconds / 3600)
const totalMinutes = Math.floor((seconds % 3600) / 60)
const totalSecondsRemaining = seconds % 60

if (totalHours < 24) {
return `${totalHours}:${totalMinutes
.toString()
.padStart(2, '0')}:${totalSecondsRemaining.toString().padStart(2, '0')}`;
return `${totalHours}:${totalMinutes.toString().padStart(2, '0')}:${totalSecondsRemaining.toString().padStart(2, '0')}`
}

return `${totalHours}h`;
return `${totalHours}h`
}

interface CalculateTimeOptions {
inSeconds?: boolean;
calculateLastTimeLog?: boolean;
inSeconds?: boolean
calculateLastTimeLog?: boolean
}

export function calculateTime(log: string, options?: CalculateTimeOptions) {
const times = parseTimeLog(log);
dayjs.extend(duration);
dayjs.extend(relativeTime);
const times = parseTimeLog(log)
dayjs.extend(duration)
dayjs.extend(relativeTime)

let seconds = 0;
let seconds = 0

if (options?.calculateLastTimeLog) {
const lastLogIndex = times.length - 1;
const lastLogIndex = times.length - 1

const start = times[lastLogIndex][0];
const startTime = start ? dayjs.unix(start) : dayjs();
const start = times[lastLogIndex][0]
const startTime = start ? dayjs.unix(start) : dayjs()

seconds += dayjs().diff(startTime, 'seconds');
seconds += dayjs().diff(startTime, 'seconds')
} else {
times.map(([start, stop]) => {
const startTime = start ? dayjs.unix(start) : dayjs();
const stopTime = stop ? dayjs.unix(stop) : dayjs();
const startTime = start ? dayjs.unix(start) : dayjs()
const stopTime = stop ? dayjs.unix(stop) : dayjs()

seconds += stopTime.diff(startTime, 'seconds');
});
seconds += stopTime.diff(startTime, 'seconds')
})
}

if (options?.inSeconds) {
return seconds.toString();
return seconds.toString()
}

return seconds > 86400
? dayjs.duration(seconds, 'seconds').humanize()
: dayjs.duration(seconds, 'seconds').format('HH:mm:ss');
return seconds > 86400 ? dayjs.duration(seconds, 'seconds').humanize() : dayjs.duration(seconds, 'seconds').format('HH:mm:ss')
}

export function calculateDifferenceBetweenLogs(log: string, logIndex: number) {
const times = parseTimeLog(log);
const logTimes = times[logIndex];
const times = parseTimeLog(log)
const logTimes = times[logIndex]

const start = logTimes ? dayjs.unix(logTimes[0]) : dayjs();
const end = logTimes ? dayjs.unix(logTimes[1]) : dayjs();
const start = logTimes ? dayjs.unix(logTimes[0]) : dayjs()
const end = logTimes ? dayjs.unix(logTimes[1]) : dayjs()

const seconds = end.diff(start, 'seconds');
const seconds = end.diff(start, 'seconds')

return new Date(seconds * 1000).toISOString().slice(11, 19);
return new Date(seconds * 1000).toISOString().slice(11, 19)
}

export const isTaskRunning = (task): boolean => {
let running = false;
let running = false

parseTimeLog(task.time_log).forEach(([, stop]) => {
if (stop === 0) {
running = true;
running = true
}
});
})

return running;
};
return running
}

export function capitalizeFirstLetter(string: string) {
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase()
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"extends": "./.wxt/tsconfig.json"
"extends": "./.wxt/tsconfig.json"
}
6 changes: 4 additions & 2 deletions uno.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import presetIcons from '@unocss/preset-icons'

export default defineConfig({
presets: [
presetIcons({ /* options */}),
presetIcons({
/* options */
})
// ...other presets
],
]
})
4 changes: 2 additions & 2 deletions views/Projects.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import {useQuery} from "@tanstack/vue-query";
import {getProjects} from "@/api";
import {useQuery} from '@tanstack/vue-query'
import {getProjects} from '@/api'
const emit = defineEmits(['project-choose'])
Expand Down
5 changes: 4 additions & 1 deletion views/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ const updateStatus = (value: string | null, key: 'beginning' | 'running' | 'fini
<a href="https://app.invoicing.co/?#/settings/task_settings">statuses</a>
for task
</h3>
<template v-for="(value, key) in statuses" style="width: 100%; display: flex; align-items: start; flex-direction: column; gap: 0.5em">
<template
v-for="(value, key) in statuses"
style="width: 100%; display: flex; align-items: start; flex-direction: column; gap: 0.5em"
>
<label :for="value || key">{{ capitalizeFirstLetter(key) }} status</label>
<template v-if="isError">
<select :id="value || key" disabled required>
Expand Down
Loading

0 comments on commit ea977f9

Please sign in to comment.