Skip to content

Commit

Permalink
Add loading indicator (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
LucaScorpion authored Feb 3, 2024
1 parent bd50702 commit a7cd855
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## v1.7.0

- Add mode for viewing chart and stats relative to contract hours.
- Add loading indicator.

## v1.6.0

Expand Down
13 changes: 13 additions & 0 deletions src/EventEmitter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export type EventHandler<T> = (value: T) => void | Promise<void>;

export class EventEmitter<T = void> {
private listeners: EventHandler<T>[] = [];

public addListener(l: EventHandler<T>) {
this.listeners.push(l);
}

public fire(value: T) {
this.listeners.forEach((h) => h(value));
}
}
23 changes: 20 additions & 3 deletions src/content/add-billability-chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { toIsoDate } from '../date';
import { endOfWeek, getWeek, startOfWeek, subWeeks } from 'date-fns';
import { calculateTimeStats } from './stats';
import { getSettings, updateSettings } from './settings';
import { render } from './index';

const api = new TimeChimpApi();

Expand Down Expand Up @@ -39,10 +38,12 @@ async function doAddBillabilityChart(date: Date, user: User) {
chartContainer = createBillabilityCard(addTimePanel);
}

updateLoadingState(true);
const [times, company] = await Promise.all([
getTimes(user.id, date, GET_TIMES_WEEKS),
api.getCompany(),
]);
updateLoadingState(false);

const settings = getSettings();

Expand Down Expand Up @@ -71,7 +72,15 @@ function createBillabilityCard(addTimePanel: Element) {

const actions = document.createElement('div');
card.appendChild(actions);
actions.className = 'actions text-align-right';
actions.className = 'actions';

const spinner = document.createElement('tc-spinner');
actions.appendChild(spinner);
spinner.className = 'title-date-spinner';
const spinnerIcon = document.createElement('i');
spinner.appendChild(spinnerIcon);
spinnerIcon.id = 'billability-loading';
spinnerIcon.className = 'fa fa-circle-o-notch fa-spin hidden';

const toggleViewBtn = document.createElement('button');

Expand All @@ -91,13 +100,21 @@ function createBillabilityCard(addTimePanel: Element) {
relativeToContractHours: !getSettings().relativeToContractHours,
});
setBtnText();
render();
});

addTimePanel.appendChild(card);
return chartContainer;
}

function updateLoadingState(loading: boolean) {
const spinner = document.getElementById('billability-loading');
if (spinner) {
loading
? spinner.classList.remove('hidden')
: spinner.classList.add('hidden');
}
}

/**
* Gets times from TimeChimp for the given weeks in the past, and filters out the ones for the given user id.
* Optionally a date can be provided, by default it will get times for the current date.
Expand Down
7 changes: 5 additions & 2 deletions src/content/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { addBillabilityChart } from './add-billability-chart';
import { Message } from '../message';
import setDefaultOptions from 'date-fns/setDefaultOptions';
import { TimeChimpApi, User } from '../TimeChimpApi';
import { settingsUpdateEvent } from './settings';

// Default date-fns options.
setDefaultOptions({
// Weeks start on Monday.
weekStartsOn: 1,
// Week number 1 should contain the 4th on January.
// Week number 1 should contain the 4th of January.
firstWeekContainsDate: 4,
});

Expand All @@ -18,6 +19,8 @@ const api = new TimeChimpApi();
let currentDate = new Date();
let currentUser: User | undefined;

settingsUpdateEvent.addListener(() => render());

/**
* Listens to incoming messages, and update the billability chart.
*/
Expand All @@ -31,7 +34,7 @@ chrome.runtime.onMessage.addListener(async (msg: Message) => {
await render(msg.userName);
});

export async function render(userName?: string) {
async function render(userName?: string) {
if (!currentUser || (userName && userName !== currentUser.userName)) {
currentUser = await getUser(userName);
}
Expand Down
5 changes: 5 additions & 0 deletions src/content/settings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { EventEmitter } from '../EventEmitter';

const STORAGE_KEY = 'tcbc-settings';

export interface Settings {
Expand All @@ -10,6 +12,8 @@ const DEFAULT_SETTINGS: Settings = {
relativeToContractHours: false,
};

export const settingsUpdateEvent = new EventEmitter();

export function getSettings(): Settings {
// Try to load the settings.
if (!settings) {
Expand All @@ -33,6 +37,7 @@ export function updateSettings(updates: Partial<Settings>) {
...updates,
};
saveSettings();
settingsUpdateEvent.fire();
}

function tryLoadSettings() {
Expand Down
8 changes: 5 additions & 3 deletions src/content/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
height: 350px;
}

.billability-card > .actions > button {
margin-right: 20px;
margin-bottom: 20px;
.billability-card > .actions {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px 20px;
}

0 comments on commit a7cd855

Please sign in to comment.