Compare commits
	
		
			No commits in common. "3f15a89d574b2b189be158bd36a227b4b8ac5924" and "54daa904be455559db212476af736fd5d06e1307" have entirely different histories. 
		
	
	
		
			3f15a89d57
			...
			54daa904be
		
	
		
	
								
									
									
										
											18
										
									
									README.md
									
									
									
									
								
								
							
							
										
											18
										
									
									README.md
									
									
									
									
								| 
						 | 
					@ -97,21 +97,3 @@ To regenerate the frontend client during development:
 | 
				
			||||||
```sh
 | 
					```sh
 | 
				
			||||||
npm run openapi-generate
 | 
					npm run openapi-generate
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					 | 
				
			||||||
## Screenshots
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Home
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Schedule
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Team
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Team Settings
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,7 +78,6 @@ nav {
 | 
				
			||||||
  margin: 0;
 | 
					  margin: 0;
 | 
				
			||||||
  align-items: center;
 | 
					  align-items: center;
 | 
				
			||||||
  justify-content: space-between;
 | 
					  justify-content: space-between;
 | 
				
			||||||
  border-bottom: 1px solid var(--surface-0);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nav .nav-links {
 | 
					nav .nav-links {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,39 +8,6 @@ export const useClientStore = defineStore("client", () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const calls = new Map<string, Promise<any>>();
 | 
					  const calls = new Map<string, Promise<any>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  type CachedValue<T> = {
 | 
					 | 
				
			||||||
    value: T,
 | 
					 | 
				
			||||||
    timestamp: number,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const cached = new Map<string, any>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function callCached<T>(
 | 
					 | 
				
			||||||
    key: string,
 | 
					 | 
				
			||||||
    apiCall: () => CancelablePromise<T>,
 | 
					 | 
				
			||||||
    maxLifetime: number = 2000,
 | 
					 | 
				
			||||||
    thenOnce?: (result: T) => T,
 | 
					 | 
				
			||||||
    catchOnce?: (error: any) => any,
 | 
					 | 
				
			||||||
    finallyOnce?: () => void,
 | 
					 | 
				
			||||||
  ): Promise<T> {
 | 
					 | 
				
			||||||
    if (cached.has(key)) {
 | 
					 | 
				
			||||||
      const cachedValue = cached.get(key) as CachedValue<T>;
 | 
					 | 
				
			||||||
      if (Date.now() - cachedValue.timestamp < maxLifetime) {
 | 
					 | 
				
			||||||
        return Promise.resolve(cachedValue.value);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // cache miss
 | 
					 | 
				
			||||||
    let promise = call(key, apiCall, thenOnce, catchOnce, finallyOnce);
 | 
					 | 
				
			||||||
    promise.then((result) => {
 | 
					 | 
				
			||||||
      cached.set(key, {
 | 
					 | 
				
			||||||
        value: result,
 | 
					 | 
				
			||||||
        timestamp: Date.now(),
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    return promise;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function call<T>(
 | 
					  function call<T>(
 | 
				
			||||||
    key: string,
 | 
					    key: string,
 | 
				
			||||||
    apiCall: () => CancelablePromise<T>,
 | 
					    apiCall: () => CancelablePromise<T>,
 | 
				
			||||||
| 
						 | 
					@ -50,15 +17,11 @@ export const useClientStore = defineStore("client", () => {
 | 
				
			||||||
  ): Promise<T> {
 | 
					  ): Promise<T> {
 | 
				
			||||||
    console.log("Fetching call " + key);
 | 
					    console.log("Fetching call " + key);
 | 
				
			||||||
    if (!calls.has(key)) {
 | 
					    if (!calls.has(key)) {
 | 
				
			||||||
      console.log("Making new call " + key);
 | 
					 | 
				
			||||||
      const promise = apiCall();
 | 
					      const promise = apiCall();
 | 
				
			||||||
      calls.set(key, promise);
 | 
					      calls.set(key, promise);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // remove from calls once completed
 | 
					      // remove from calls once completed
 | 
				
			||||||
      promise.finally(() => {
 | 
					      promise.finally(() => calls.delete(key));
 | 
				
			||||||
        console.log("Call " + key + " completed");
 | 
					 | 
				
			||||||
        calls.delete(key);
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // only execute this "then" once if the call was just freshly made
 | 
					      // only execute this "then" once if the call was just freshly made
 | 
				
			||||||
      if (thenOnce) {
 | 
					      if (thenOnce) {
 | 
				
			||||||
| 
						 | 
					@ -74,8 +37,6 @@ export const useClientStore = defineStore("client", () => {
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return promise;
 | 
					      return promise;
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      console.log("Returning concurrent call " + key);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return calls.get(key) as Promise<T>;
 | 
					    return calls.get(key) as Promise<T>;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -83,7 +44,6 @@ export const useClientStore = defineStore("client", () => {
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    client,
 | 
					    client,
 | 
				
			||||||
    call,
 | 
					    call,
 | 
				
			||||||
    callCached,
 | 
					 | 
				
			||||||
    calls,
 | 
					    calls,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ export const useTeamsStore = defineStore("teams", () => {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async function fetchTeam(id: number) {
 | 
					  async function fetchTeam(id: number) {
 | 
				
			||||||
    const response = await clientStore.callCached(
 | 
					    const response = await clientStore.call(
 | 
				
			||||||
      fetchTeam.name,
 | 
					      fetchTeam.name,
 | 
				
			||||||
      () => client.default.getTeam(id)
 | 
					      () => client.default.getTeam(id)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,7 @@ export const useTeamsStore = defineStore("teams", () => {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async function fetchTeamMembers(id: number) {
 | 
					  async function fetchTeamMembers(id: number) {
 | 
				
			||||||
    const response = await clientStore.callCached(
 | 
					    const response = await clientStore.call(
 | 
				
			||||||
      fetchTeamMembers.name,
 | 
					      fetchTeamMembers.name,
 | 
				
			||||||
      () => client.default.getTeamMembers(id)
 | 
					      () => client.default.getTeamMembers(id)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,7 +117,7 @@ class Event(app_db.BaseModel):
 | 
				
			||||||
            f"Maximum roles filled: {matchings}" + ringers_needed_msg,
 | 
					            f"Maximum roles filled: {matchings}" + ringers_needed_msg,
 | 
				
			||||||
            "",
 | 
					            "",
 | 
				
			||||||
            "[Confirm attendance here]" +
 | 
					            "[Confirm attendance here]" +
 | 
				
			||||||
                f"(https://{domain}/team/id/{self.team.id})",
 | 
					                f"(https://{domain}/team/id/{self.team.id}/events/{self.id})",
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_or_create_webhook(self):
 | 
					    def get_or_create_webhook(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
											
												Binary file not shown.
											
										
									
								| 
		 Before Width: | Height: | Size: 97 KiB  | 
											
												Binary file not shown.
											
										
									
								| 
		 Before Width: | Height: | Size: 107 KiB  | 
											
												Binary file not shown.
											
										
									
								| 
		 Before Width: | Height: | Size: 115 KiB  | 
											
												Binary file not shown.
											
										
									
								| 
		 Before Width: | Height: | Size: 221 KiB  | 
		Loading…
	
		Reference in New Issue