Compare commits
3 Commits
6233189a49
...
3ec9056901
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ec9056901 | ||
|
|
071c41b70c | ||
|
|
0726a8d3ba |
5356
package-lock.json
generated
5356
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
64
package.json
64
package.json
@@ -12,54 +12,54 @@
|
||||
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.3",
|
||||
"@pvermeer/dexie-encrypted-addon": "^2.0.5",
|
||||
"@tweenjs/tween.js": "^20.0.3",
|
||||
"@veramo/core": "^5.1.2",
|
||||
"@veramo/credential-w3c": "^5.1.4",
|
||||
"@veramo/data-store": "^5.1.2",
|
||||
"@pvermeer/dexie-encrypted-addon": "^3.0.0",
|
||||
"@tweenjs/tween.js": "^21.0.0",
|
||||
"@veramo/core": "^5.2.0",
|
||||
"@veramo/credential-w3c": "^5.2.0",
|
||||
"@veramo/data-store": "^5.2.0",
|
||||
"@veramo/did-manager": "^5.1.2",
|
||||
"@veramo/did-provider-ethr": "^5.1.2",
|
||||
"@veramo/did-resolver": "^5.1.2",
|
||||
"@veramo/did-resolver": "^5.2.0",
|
||||
"@veramo/key-manager": "^5.1.2",
|
||||
"@vueuse/core": "^9.13.0",
|
||||
"@vueuse/core": "^10.2.0",
|
||||
"@zxing/text-encoding": "^0.9.0",
|
||||
"axios": "^1.3.4",
|
||||
"axios": "^1.4.0",
|
||||
"buffer": "^6.0.3",
|
||||
"class-transformer": "^0.5.1",
|
||||
"core-js": "^3.29.1",
|
||||
"dexie": "^3.2.3",
|
||||
"core-js": "^3.31.0",
|
||||
"dexie": "^3.2.4",
|
||||
"dexie-export-import": "^4.0.7",
|
||||
"did-jwt": "^6.11.5",
|
||||
"ethereum-cryptography": "^1.2.0",
|
||||
"did-jwt": "^7.2.2",
|
||||
"ethereum-cryptography": "^2.0.0",
|
||||
"ethereumjs-util": "^7.1.5",
|
||||
"ethr-did-resolver": "^8.0.0",
|
||||
"js-generate-password": "^0.1.7",
|
||||
"js-generate-password": "^0.1.9",
|
||||
"localstorage-slim": "^2.4.0",
|
||||
"luxon": "^3.3.0",
|
||||
"merkletreejs": "^0.3.9",
|
||||
"merkletreejs": "^0.3.10",
|
||||
"moment": "^2.29.4",
|
||||
"papaparse": "^5.4.1",
|
||||
"pina": "^0.20.2204228",
|
||||
"pinia-plugin-persistedstate": "^3.1.0",
|
||||
"qr-code-generator-vue3": "^1.4.21",
|
||||
"ramda": "^0.28.0",
|
||||
"readable-stream": "^4.3.0",
|
||||
"ramda": "^0.29.0",
|
||||
"readable-stream": "^4.4.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"register-service-worker": "^1.7.2",
|
||||
"three": "^0.152.2",
|
||||
"vue": "^3.2.47",
|
||||
"three": "^0.153.0",
|
||||
"vue": "^3.3.4",
|
||||
"vue-axios": "^3.5.2",
|
||||
"vue-class-component": "^8.0.0-0",
|
||||
"vue-facing-decorator": "^2.1.19",
|
||||
"vue-facing-decorator": "^2.1.20",
|
||||
"vue-property-decorator": "^9.1.2",
|
||||
"vue-router": "^4.1.6",
|
||||
"web-did-resolver": "^2.0.22"
|
||||
"vue-router": "^4.2.2",
|
||||
"web-did-resolver": "^2.0.24"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/ramda": "^0.28.23",
|
||||
"@types/three": "^0.152.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.57.0",
|
||||
"@typescript-eslint/parser": "^5.57.0",
|
||||
"@types/ramda": "^0.29.2",
|
||||
"@types/three": "^0.152.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
||||
"@typescript-eslint/parser": "^5.60.0",
|
||||
"@vue/cli-plugin-babel": "~5.0.8",
|
||||
"@vue/cli-plugin-eslint": "~5.0.8",
|
||||
"@vue/cli-plugin-pwa": "~5.0.8",
|
||||
@@ -67,15 +67,15 @@
|
||||
"@vue/cli-plugin-typescript": "~5.0.8",
|
||||
"@vue/cli-plugin-vuex": "~5.0.8",
|
||||
"@vue/cli-service": "~5.0.8",
|
||||
"@vue/eslint-config-typescript": "^11.0.2",
|
||||
"@vue/eslint-config-typescript": "^11.0.3",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"eslint": "^8.37.0",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-vue": "^9.10.0",
|
||||
"postcss": "^8.4.21",
|
||||
"prettier": "^2.8.7",
|
||||
"tailwindcss": "^3.3.1",
|
||||
"typescript": "~5.0.3"
|
||||
"eslint-plugin-vue": "^9.15.0",
|
||||
"postcss": "^8.4.24",
|
||||
"prettier": "^2.8.8",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"typescript": "~5.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,29 +10,53 @@ import { Component, Emit, Prop, Vue } from "vue-facing-decorator";
|
||||
|
||||
@Component
|
||||
export default class InfiniteScroll extends Vue {
|
||||
@Prop({ default: 100 })
|
||||
@Prop({ default: 200 })
|
||||
readonly distance!: number;
|
||||
private observer!: IntersectionObserver;
|
||||
private isInitialRender = true;
|
||||
|
||||
// 'mounted' hook runs after initial render
|
||||
mounted() {
|
||||
const options = {
|
||||
root: this.$refs.scrollContainer as HTMLElement,
|
||||
rootMargin: `0px 0px ${this.distance}px 0px`,
|
||||
threshold: 1.0,
|
||||
};
|
||||
this.observer = new IntersectionObserver(this.handleIntersection, options);
|
||||
this.observer.observe(this.$refs.sentinel as HTMLElement);
|
||||
updated() {
|
||||
console.log("updated()");
|
||||
if (!this.observer) {
|
||||
const options = {
|
||||
root: null,
|
||||
rootMargin: `0px 0px ${this.distance}px 0px`,
|
||||
threshold: 1.0,
|
||||
};
|
||||
this.observer = new IntersectionObserver(
|
||||
this.handleIntersection,
|
||||
options
|
||||
);
|
||||
this.observer.observe(this.$refs.sentinel as HTMLElement);
|
||||
}
|
||||
}
|
||||
|
||||
// 'beforeUnmount' hook runs before unmounting the component
|
||||
beforeUnmount() {
|
||||
this.observer.disconnect();
|
||||
if (this.observer) {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Emit("reached-bottom")
|
||||
handleIntersection(entries: IntersectionObserverEntry[]) {
|
||||
console.log("handleIntersection");
|
||||
const entry = entries[0];
|
||||
if (entry.isIntersecting) {
|
||||
const distance = entry.boundingClientRect.top - entry.rootBounds.top;
|
||||
console.log("distance: ", distance);
|
||||
console.log("intersectionRatio", entry.intersectionRatio);
|
||||
const sentinelPosition = (
|
||||
this.$refs.sentinel as HTMLElement
|
||||
).getBoundingClientRect();
|
||||
// Access sentinel element's position properties
|
||||
const sentinelTop = sentinelPosition.top;
|
||||
console.log("sentinelTop", sentinelTop);
|
||||
const scrollContainer = (
|
||||
this.$refs.scrollContainer as HTMLElement
|
||||
).getBoundingClientRect();
|
||||
// Access scrollContainer properties or perform any necessary actions
|
||||
console.log("scrollContainerTop", scrollContainer);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -230,9 +230,10 @@ export default class NewEditProjectView extends Vue {
|
||||
const serverError = error as AxiosError;
|
||||
if (serverError) {
|
||||
this.isAlertVisible = true;
|
||||
if (serverError.message) {
|
||||
if (Object.prototype.hasOwnProperty.call(serverError, "message")) {
|
||||
console.log(serverError);
|
||||
this.alertTitle = "User Message";
|
||||
userMessage = serverError.message; // This is info for the user.
|
||||
userMessage = serverError.response.data.error.message; // This is info for the user.
|
||||
this.alertMessage = userMessage;
|
||||
} else {
|
||||
this.alertTitle = "Server Message";
|
||||
|
||||
@@ -71,50 +71,102 @@
|
||||
</button>
|
||||
|
||||
<!-- Results List -->
|
||||
<ul class="">
|
||||
<li
|
||||
class="border-b border-slate-300"
|
||||
v-for="project in projects"
|
||||
:key="project.handleId"
|
||||
>
|
||||
<a
|
||||
@click="onClickLoadProject(project.handleId)"
|
||||
class="block py-4 flex gap-4"
|
||||
<InfiniteScroll @reached-bottom="loadMoreData">
|
||||
<ul>
|
||||
<li
|
||||
class="border-b border-slate-300"
|
||||
v-for="project in projects"
|
||||
:key="project.handleId"
|
||||
>
|
||||
<div class="flex-none w-12">
|
||||
<img
|
||||
src="https://picsum.photos/200/200?random=1"
|
||||
class="w-full rounded"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grow overflow-hidden">
|
||||
<h2 class="text-base font-semibold">{{ project.name }}</h2>
|
||||
<div class="text-sm truncate">
|
||||
{{ project.description }}
|
||||
<a
|
||||
@click="onClickLoadProject(project.handleId)"
|
||||
class="block py-4 flex gap-4"
|
||||
>
|
||||
<div class="flex-none w-12">
|
||||
<img
|
||||
src="https://picsum.photos/200/200?random=1"
|
||||
class="w-full rounded"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="grow overflow-hidden">
|
||||
<h2 class="text-base font-semibold">{{ project.name }}</h2>
|
||||
<div class="text-sm truncate">
|
||||
{{ project.description }}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</InfiniteScroll>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import * as R from "ramda";
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
|
||||
import { accountsDB, db } from "@/db";
|
||||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||
import { accessToken } from "@/libs/crypto";
|
||||
import { IIdentifier } from "@veramo/core";
|
||||
import InfiniteScroll from "@/components/InfiniteScroll";
|
||||
|
||||
@Options({
|
||||
components: {},
|
||||
@Component({
|
||||
components: { InfiniteScroll },
|
||||
})
|
||||
export default class ProjectsView extends Vue {
|
||||
apiServer = "";
|
||||
projects: { handleId: string; name: string; description: string }[] = [];
|
||||
current: IIdentifier;
|
||||
isDataLoaded = false;
|
||||
|
||||
async loadMoreData(payload: boolean) {
|
||||
console.log("loadMoreData");
|
||||
console.log(payload);
|
||||
if (this.projects.length > 0) {
|
||||
console.log(this.projects[this.projects.length - 1]);
|
||||
const afterurl = this.projects[this.projects.length - 1]["handleId"];
|
||||
const regex = /([0-9A-Z]+)$/; // Regular expression to match one or more digits at the end
|
||||
const matches = afterurl.match(regex);
|
||||
|
||||
let afterId = "";
|
||||
if (matches && matches.length > 1) {
|
||||
afterId = matches[1];
|
||||
console.log(afterId); // Output: 01H3HBVZGH3YE0K27X35S15QT1
|
||||
} else {
|
||||
console.log("No digits found at the end of the URL.");
|
||||
return;
|
||||
}
|
||||
const url =
|
||||
this.apiServer + "/api/v2/report/plansByIssuer?afterId=" + afterId;
|
||||
const token = await accessToken(this.current);
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: "Bearer " + token,
|
||||
};
|
||||
|
||||
try {
|
||||
const resp = await this.axios.get(url, { headers });
|
||||
if (resp.status === 200) {
|
||||
const plans = resp.data.data;
|
||||
for (let i = 0; i < plans.length; i++) {
|
||||
const plan = plans[i];
|
||||
const data = {
|
||||
name: plan.name,
|
||||
description: plan.description,
|
||||
// handleId is new in server v release-1.6.0; remove fullIri when that
|
||||
// version shows up here: https://endorser.ch:3000/api-docs/
|
||||
handleId: plan.handleId || plan.fullIri,
|
||||
};
|
||||
this.projects.push(data);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Got error loading projects: ", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClickLoadProject(id: string) {
|
||||
localStorage.setItem("projectId", id);
|
||||
@@ -125,6 +177,7 @@ export default class ProjectsView extends Vue {
|
||||
}
|
||||
|
||||
async LoadProjects(identity: IIdentifier) {
|
||||
console.log("LoadProjects");
|
||||
const url = this.apiServer + "/api/v2/report/plansByIssuer";
|
||||
const token = await accessToken(identity);
|
||||
const headers = {
|
||||
@@ -147,6 +200,8 @@ export default class ProjectsView extends Vue {
|
||||
};
|
||||
this.projects.push(data);
|
||||
}
|
||||
|
||||
this.isDataLoaded = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Got error loading projects: ", error);
|
||||
|
||||
Reference in New Issue
Block a user