Replace Table with responsive Card. Add refresh of token and retry on 401 errors

This commit is contained in:
2019-01-18 14:03:58 +01:00
parent d4f432f422
commit 86486795f6
11 changed files with 230 additions and 248 deletions
+35
View File
@@ -0,0 +1,35 @@
<template>
<Card dis-hover>
<p slot="title">{{event.band.name}}</p>
<a href="#" slot="extra" v-if="hasUser" @click.prevent="ignore('band', event.band.name)"><Icon type="ios-eye-off" title="Dölj"></Icon></a>
<Row>
<Col :xs="24" :sm="12"><strong>Datum:</strong> {{event.date}}</Col>
<Col :xs="24" :sm="12" v-if="event.time"><strong>Tid:</strong> {{event.time}}</Col>
</Row>
<Row>
<Col :xs="24" :sm="12" :md="6"><strong>Var:</strong> {{event.danceHall.name}} <a href="#" v-if="hasUser" @click.prevent="ignore('danceHall', event.danceHall.name)"><Icon type="ios-eye-off" title="Dölj"></Icon></a></Col>
<Col :xs="24" :sm="12" :md="6"><strong>Ort:</strong> {{event.danceHall.city}} <a href="#" v-if="hasUser" @click.prevent="ignore('city', event.danceHall.city)"><Icon type="ios-eye-off" title="Dölj"></Icon></a></Col>
<Col :xs="24" :sm="12" :md="6"><strong>Kommun:</strong> {{event.danceHall.municipality}} <a href="#" v-if="hasUser" @click.prevent="ignore('municipality', event.danceHall.municipality)"><Icon type="ios-eye-off" title="Dölj"></Icon></a></Col>
<Col :xs="24" :sm="12" :md="6"><strong>Län:</strong> {{event.danceHall.state}} <a href="#" v-if="hasUser" @click.prevent="ignore('state', event.danceHall.state)"><Icon type="ios-eye-off" title="Dölj"></Icon></a></Col>
</Row>
</Card>
</template>
<script>
export default {
props: {
event: {
type: Object,
required: true
},
hasUser: {
type: Boolean,
required: true
},
ignore: {
type: Function,
required: true
}
}
};
</script>
+53 -180
View File
@@ -2,7 +2,14 @@
<div>
<app-loader :show="isLoading" />
<div v-if="isReady || isSubmitting || isSubmitted" class="container app-fade-in">
<Table stripe border :columns="columns" :data="events"></Table>
<Content>
<Row :gutter="16" type="flex" justify="space-around" v-for="event in events" :key="event.id" class-name="eventRow">
<Col span="22">
<Event :event="event" :has-user="hasUser" :ignore="ignore"></Event>
</Col>
</Row>
<br>
</Content>
</div>
</div>
</template>
@@ -19,29 +26,11 @@
import auth from "~/utils/auth";
// import LoadFailed from "./Messages/LoadFailed";
// import NotViewable from "./Messages/NotViewable";
// import SubmitFailed from "./Messages/SubmitFailed";
// import SubmitSuccessful from "./Messages/SubmitSuccessful";
// import Alerts from "./Alerts";
// import TopBar from "./TopBar";
// import PackageSelector from "./PackageSelector";
// import ProductsForm from "./ProductsForm";
// import PropertyInfo from "./Info";
// import RealtorFrame from "./RealtorFrame";
import Event from "./Event";
export default {
components: {
// Alerts,
// LoadFailed,
// NotViewable,
// TopBar,
// PackageSelector,
// ProductsForm,
// PropertyInfo,
// RealtorFrame,
// SubmitFailed,
// SubmitSuccessful
Event
},
data() {
return {
@@ -54,136 +43,7 @@
selectedPackage: undefined,
selectedImages: [],
submitError: "",
user: undefined,
columns: [
{
title: 'Datum',
key: 'date'
},
{
title: 'Tid',
key: 'time'
},
{
title: 'Band',
render: (h, params) => {
const inner = Array(h('span', ' ' + params.row.band.name + ' '));
if (this.hasUser) {
inner.push(h('Icon', {
props: {
type: 'ios-eye-off'
},
attrs: {
title: 'Dölj'
},
on: {
click: () => {
this.ignoreBand({name: params.row.band.name})
}
}
}, 'Dölj'));
}
return h('div', inner);
}
},
{
title: 'Dansställe',
render: (h, params) => {
const inner = Array(h('span', ' ' + params.row.danceHall.name + ' '));
if (this.hasUser) {
inner.push(h('Icon', {
props: {
type: 'ios-eye-off'
},
attrs: {
title: 'Dölj'
},
on: {
click: () => {
this.ignoreDanceHall({name: params.row.danceHall.name})
}
}
}, 'Dölj'));
}
return h('div', inner);
}
},
{
title: 'Stad',
render: (h, params) => {
const inner = Array(h('span', ' ' + params.row.danceHall.city + ' '));
if (this.hasUser) {
inner.push(h('Icon', {
props: {
type: 'ios-eye-off'
},
attrs: {
title: 'Dölj'
},
on: {
click: () => {
this.ignoreCity({name: params.row.danceHall.city})
}
}
}, 'Dölj'));
}
return h('div', inner);
}
},
{
title: 'Kommun',
render: (h, params) => {
const inner = Array(h('span', ' ' + params.row.danceHall.municipality + ' '));
if (this.hasUser) {
inner.push(h('Icon', {
props: {
type: 'ios-eye-off'
},
attrs: {
title: 'Dölj'
},
on: {
click: () => {
this.ignoreMunicipality({name: params.row.danceHall.municipality})
}
}
}, 'Dölj'));
}
return h('div', inner);
}
},
{
title: 'Län',
render: (h, params) => {
const inner = Array(h('span', ' ' + params.row.danceHall.state + ' '));
if (this.hasUser) {
inner.push(h('Icon', {
props: {
type: 'ios-eye-off'
},
attrs: {
title: 'Dölj'
},
on: {
click: () => {
this.ignoreState({name: params.row.danceHall.state})
}
}
}, 'Dölj'));
}
return h('div', inner);
}
},
{
title: 'Övrigt',
key: 'extraInfo'
}
]
user: undefined
};
},
computed: {
@@ -209,7 +69,7 @@
return this.status === "no-packages";
},
hasUser() {
return this.user;
return this.user !== undefined && this.user !== null;
}
},
mounted() {
@@ -237,36 +97,45 @@
fetchUser() {
this.user = auth.getUserInfo();
},
ignoreBand(name) {
ignoreBand(name)
.then(this.ignoreSuccess)
.catch(this.ignoreFailed)
ignore(type, name) {
switch (type) {
case 'band':
ignoreBand({name: name})
.then(this.ignoreSuccess(name))
.catch(this.ignoreFailed);
break;
case 'danceHall':
ignoreDanceHall({name: name})
.then(this.ignoreSuccess(name))
.catch(this.ignoreFailed);
break;
case 'city':
ignoreCity({name: name})
.then(this.ignoreSuccess(name))
.catch(this.ignoreFailed);
break;
case 'municipality':
ignoreMunicipality({name: name}
.then(this.ignoreSuccess(name))
.catch(this.ignoreFailed));
break;
case 'state':
ignoreState({name: name})
.then(this.ignoreSuccess(name))
.catch(this.ignoreFailed);
break;
}
},
ignoreDanceHall(name) {
ignoreDanceHall(name)
.then(this.ignoreSuccess)
.catch(this.ignoreFailed)
ignoreSuccess(name) {
return () => {
this.$Message.success(`${name} har dolts`);
this.fetchEvents();
}
},
ignoreCity(name) {
ignoreCity(name)
.then(this.ignoreSuccess)
.catch(this.ignoreFailed)
},
ignoreMunicipality(name) {
ignoreMunicipality(name)
.then(this.ignoreSuccess)
.catch(this.ignoreFailed)
},
ignoreState(name) {
ignoreState(name)
.then(this.ignoreSuccess)
.catch(this.ignoreFailed)
},
ignoreSuccess(response) {
this.fetchEvents()
},
ignoreFailed() {
ignoreFailed(name) {
return () => {
this.$Message.error(`${name} kunde inte döljas`);
}
}
// switchPackage(pack) {
// this.selectedPackage = pack;
@@ -334,6 +203,10 @@
position: relative;
}
.eventRow {
margin-bottom: 1.5rem;
}
@media screen and(max-width: 1200px) {
.left {
width: 40vw;
+5 -1
View File
@@ -7,10 +7,14 @@
"author": "Joakim Olsson <joakim@unbound.se>",
"private": true,
"dependencies": {
"apollo-fetch": "^0.7.0",
"apollo-link": "^1.2.6",
"apollo-link-error": "^1.1.5",
"apollo-link-http": "^1.5.9",
"auth0-js": "^9.9.0",
"eslint": "^5.1.0",
"eslint-plugin-vue": "^4.5.0",
"graphql": "^14.1.1",
"graphql-tag": "^2.10.1",
"iview": "^3.0.0",
"lodash": "^4.17.10",
"node-sass": "^4.9.0",
+2 -2
View File
@@ -23,9 +23,9 @@ if (config.dev) {
// Add graphql mocking middleware
//addGraphMiddleware(app);
app.use('/graph', proxy('localhost:8081', {
app.use('/graph/', proxy('localhost:8081', {
proxyReqPathResolver: function (req) {
return '/graph';
return '/graph/';
}
}
)
+10
View File
@@ -64,6 +64,16 @@ export default class AuthenticationClient {
window.location.href = url;
}
checkSession(resolve, reject) {
this.webAuth.checkSession({state: {}}, (err, result) => {
if (err) {
return reject(err || 'Re-authentication failed');
} else {
return this.storeSession(result, resolve, reject);
}
});
}
storeSession(authResult, resolve, reject) {
this.webAuth.client.userInfo(authResult.accessToken, (err, user) => {
if (err) {
+1 -1
View File
@@ -8,7 +8,7 @@ const auth0Config = {
domain: "unbound.eu.auth0.com",
clientID: "orQfnvCPUR5C3mJkKoiWLQHOVQsBn60e",
redirectUri: getRedirectUri(),
audience: "https://unbound.eu.auth0.com/userinfo",
audience: "http://dancefinder.unbound.se",
responseType: "token id_token",
scope: "openid profile"
};
+8 -12
View File
@@ -1,15 +1,11 @@
const webAuth = require("../auth").default;
module.exports = {
includeCredentials: (tokenFn) => {
return ({options}, next) => {
if (!options.headers) {
options.headers = {}; // Create the headers object if needed.
}
const token = tokenFn();
if (token) {
options.headers['Authorization'] = 'Bearer ' + tokenFn();
}
options.credentials = 'same-origin'; // eslint-disable-line
next();
includeCredentials: (uri, options) => {
const token = webAuth.idToken();
if (token) {
options.headers['Authorization'] = 'Bearer ' + token;
}
},
return fetch(uri, options);
}
};
+5 -6
View File
@@ -6,22 +6,21 @@ import {
ignoreMunicipalityMutation,
ignoreStateMutation,
} from './mutationStrings';
import webAuth from '../auth';
/* eslint-disable max-len */
export const ignoreBand = variables => {
return createQuery(webAuth.idToken, ignoreBandMutation, variables)
return createQuery(ignoreBandMutation, variables)
};
export const ignoreDanceHall = variables => {
return createQuery(webAuth.idToken, ignoreDanceHallMutation, variables)
return createQuery(ignoreDanceHallMutation, variables)
};
export const ignoreCity = variables => {
return createQuery(webAuth.idToken, ignoreCityMutation, variables)
return createQuery(ignoreCityMutation, variables)
};
export const ignoreMunicipality = variables => {
return createQuery(webAuth.idToken, ignoreMunicipalityMutation, variables)
return createQuery(ignoreMunicipalityMutation, variables)
};
export const ignoreState = variables => {
return createQuery(webAuth.idToken, ignoreStateMutation, variables)
return createQuery(ignoreStateMutation, variables)
};
/* eslint-enable max-len */
+1 -3
View File
@@ -2,9 +2,7 @@ import { createQuery } from './utils';
import {
eventQuery,
} from './queryStrings';
import webAuth from '../auth';
/* eslint-disable max-len */
export const findEvents = () => createQuery(webAuth.idToken, eventQuery);
export const findEvents = () => createQuery(eventQuery);
/* eslint-enable max-len */
+43 -8
View File
@@ -1,13 +1,48 @@
const { createApolloFetch } = require('apollo-fetch');
import { execute, makePromise, ApolloLink } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import gql from 'graphql-tag';
const { includeCredentials } = require('./middleware');
import { onError } from 'apollo-link-error';
import { default as webAuth} from '../auth';
const defaultGraphUri = '/graph/';
const httpLink = new HttpLink({ uri: defaultGraphUri, fetch: includeCredentials, credentials: 'same-origin' });
const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
if (graphQLErrors) {
console.log('GraphQL errors:', graphQLErrors);
// for (let err of graphQLErrors) {
// switch (err.extensions.code) {
// case 'UNAUTHENTICATED':
// // error code is set to UNAUTHENTICATED
// // when AuthenticationError thrown in resolver
//
// // modify the operation context with a new token
// }
// }
}
if (networkError) {
if (networkError.statusCode === 401) {
webAuth.checkSession((response) => {
const oldHeaders = operation.getContext().headers;
operation.setContext({
headers: {
...oldHeaders,
authorization: webAuth.idToken(),
},
});
return forward(operation);
}, (err) => {
console.log(err);
});
}
}
}
);
export const createQuery = (tokenFn, query, variables) => { // eslint-disable-line
const apollo = createApolloFetch({ uri: defaultGraphUri });
apollo.use(includeCredentials(tokenFn));
// apollo.useAfter(trackErrors);
return apollo({ query, variables });
export const createQuery = (query, variables) => { // eslint-disable-line
const operation = {
query: gql(query),
variables: variables
};
return makePromise(execute(ApolloLink.from([errorLink, httpLink]), operation));
};
+67 -35
View File
@@ -1300,12 +1300,43 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
apollo-fetch@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/apollo-fetch/-/apollo-fetch-0.7.0.tgz#63c255a0ccb1b4c473524d8f9b536d72438bd3e7"
integrity sha512-0oHsDW3Zxx+Of1wuqcOXruNj4Kv55WN69tkIjwkCQDEIrgCpgA2scjChFsgflSVMy/1mkTKCY1Mc0TYJhNRzmw==
apollo-link-error@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.1.5.tgz#1d600dfa75c4e4bf017f50d60da7b375b53047ab"
integrity sha512-gE0P711K+rI3QcTzfYhzRI9axXaiuq/emu8x8Y5NHK9jl9wxh7qmEc3ZTyGpnGFDDTXfhalmX17X5lp3RCVHDQ==
dependencies:
cross-fetch "^1.0.0"
apollo-link "^1.2.6"
apollo-link-http-common "^0.2.8"
apollo-link-http-common@^0.2.8:
version "0.2.8"
resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.8.tgz#c6deedfc2739db8b11013c3c2d2ccd657152941f"
integrity sha512-gGmXZN8mr7e9zjopzKQfZ7IKnh8H12NxBDzvp9nXI3U82aCVb72p+plgoYLcpMY8w6krvoYjgicFmf8LO20TCQ==
dependencies:
apollo-link "^1.2.6"
apollo-link-http@^1.5.9:
version "1.5.9"
resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.9.tgz#9046f5640a94c8a8b508a39e0f2c628b781baecc"
integrity sha512-9tJy2zGm4Cm/1ycScDNZJe51dgnTSfKx7pKIgPZmcxkdDpgUY2DZitDH6ZBv4yp9z8MC9Xr9wgwc29s6hcadUQ==
dependencies:
apollo-link "^1.2.6"
apollo-link-http-common "^0.2.8"
apollo-link@^1.2.6:
version "1.2.6"
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.6.tgz#d9b5676d79c01eb4e424b95c7171697f6ad2b8da"
integrity sha512-sUNlA20nqIF3gG3F8eyMD+mO80fmf3dPZX+GUOs3MI9oZR8ug09H3F0UsWJMcpEg6h55Yy5wZ+BMmAjrbenF/Q==
dependencies:
apollo-utilities "^1.0.0"
zen-observable-ts "^0.8.13"
apollo-utilities@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.1.0.tgz#e7603f834b57e4e109be6b450dc1cc1037aac94c"
integrity sha512-D3scmF6vJkCBECMasMEc0J9dNNHVULl6h2d7/oGJxWid1fgcAPHZJN5XLCZisuOfn0Dvvu3Unf/zK00Z3e49Qg==
dependencies:
fast-json-stable-stringify "^2.0.0"
aproba@^1.0.3, aproba@^1.1.1:
version "1.2.0"
@@ -2388,14 +2419,6 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
cross-fetch@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-1.1.1.tgz#dede6865ae30f37eae62ac90ebb7bdac002b05a0"
integrity sha512-+VJE04+UfxxmBfcnmAu/lKor53RUCx/1ilOti4p+JgrnLQ4AZZIRoe2OEd76VaHyWQmQxqKnV+TaqjHC4r0HWw==
dependencies:
node-fetch "1.7.3"
whatwg-fetch "2.0.3"
cross-spawn@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982"
@@ -3034,13 +3057,6 @@ encodeurl@~1.0.1, encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
encoding@^0.1.11:
version "0.1.12"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=
dependencies:
iconv-lite "~0.4.13"
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
@@ -3838,6 +3854,18 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
graphql-tag@^2.10.1:
version "2.10.1"
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02"
integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg==
graphql@^14.1.1:
version "14.1.1"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.1.1.tgz#d5d77df4b19ef41538d7215d1e7a28834619fac0"
integrity sha512-C5zDzLqvfPAgTtP8AUPIt9keDabrdRAqSWjj2OPRKrKxI9Fb65I36s1uCs1UUBFnSWTdO7hyHi7z1ZbwKMKF6Q==
dependencies:
iterall "^1.2.2"
gzip-size@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80"
@@ -4079,7 +4107,7 @@ iconv-lite@0.4.23:
dependencies:
safer-buffer ">= 2.1.2 < 3"
iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
iconv-lite@^0.4.24, iconv-lite@^0.4.4:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -4472,7 +4500,7 @@ is-resolvable@^1.0.0:
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
is-stream@^1.0.1, is-stream@^1.1.0:
is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
@@ -4545,6 +4573,11 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
iterall@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7"
integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==
iview@^3.0.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/iview/-/iview-3.2.1.tgz#ea578948408a21f4c74c168dba19ee8fa04bd5e0"
@@ -5337,14 +5370,6 @@ no-case@^2.2.0:
dependencies:
lower-case "^1.1.1"
node-fetch@1.7.3:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
dependencies:
encoding "^0.1.11"
is-stream "^1.0.1"
node-fetch@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5"
@@ -8487,11 +8512,6 @@ webpackbar@^3.1.3:
text-table "^0.2.0"
wrap-ansi "^4.0.0"
whatwg-fetch@2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
integrity sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=
which-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
@@ -8643,3 +8663,15 @@ yauzl@2.8.0:
dependencies:
buffer-crc32 "~0.2.3"
fd-slicer "~1.0.1"
zen-observable-ts@^0.8.13:
version "0.8.13"
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.13.tgz#ae1fd77c84ef95510188b1f8bca579d7a5448fc2"
integrity sha512-WDb8SM0tHCb6c0l1k60qXWlm1ok3zN9U4VkLdnBKQwIYwUoB9psH7LIFgR+JVCCMmBxUgOjskIid8/N02k/2Bg==
dependencies:
zen-observable "^0.8.0"
zen-observable@^0.8.0:
version "0.8.11"
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.11.tgz#d3415885eeeb42ee5abb9821c95bb518fcd6d199"
integrity sha512-N3xXQVr4L61rZvGMpWe8XoCGX8vhU35dPyQ4fm5CY/KDlG0F75un14hjbckPXTDuKUY6V0dqR2giT6xN8Y4GEQ==