@genspectrum/dashboard-components 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,7 @@ import z from 'zod';
7
7
 
8
8
  import { lapisContext } from './lapis-context';
9
9
  import { mutationAnnotationsContext } from './mutation-annotations-context';
10
+ import { mutationLinkTemplateContext } from './mutation-link-template-context';
10
11
  import { referenceGenomeContext } from './reference-genome-context';
11
12
  import { type ReferenceGenome } from '../lapisApi/ReferenceGenome';
12
13
  import { fetchReferenceGenome } from '../lapisApi/lapisApi';
@@ -59,6 +60,22 @@ export class AppComponent extends LitElement {
59
60
  aminoAcidPositions?: string[];
60
61
  }[] = [];
61
62
 
63
+ /**
64
+ * Supply a link template for nucleotide and amino acid mutations.
65
+ * The template should include '{{mutation}}' where the mutation code will be inserted, for example:
66
+ *
67
+ * https://my-site.org/query?nucleotideMutation={{mutation}}
68
+ */
69
+ @provide({ context: mutationLinkTemplateContext })
70
+ @property({ type: Object })
71
+ mutationLinkTemplate: {
72
+ nucleotideMutation?: string;
73
+ aminoAcidMutation?: string;
74
+ } = {
75
+ nucleotideMutation: undefined,
76
+ aminoAcidMutation: undefined,
77
+ };
78
+
62
79
  /**
63
80
  * @internal
64
81
  */
@@ -0,0 +1,13 @@
1
+ import { createContext } from '@lit/context';
2
+ import z from 'zod';
3
+
4
+ export const mutationLinkTemplateSchema = z.object({
5
+ nucleotideMutation: z.string().optional(),
6
+ aminoAcidMutation: z.string().optional(),
7
+ });
8
+
9
+ export type MutationLinkTemplate = z.infer<typeof mutationLinkTemplateSchema>;
10
+
11
+ export const mutationLinkTemplateContext = createContext<MutationLinkTemplate>(
12
+ Symbol('mutation-link-template-context'),
13
+ );
@@ -0,0 +1,27 @@
1
+ import { Meta } from '@storybook/blocks';
2
+
3
+ <Meta title='Concepts/External Mutation Links' />
4
+
5
+ # External Mutation Links
6
+
7
+ When inspecting mutations, you might want to be able to quickly look up a mutation somewhere else.
8
+ For this, it's possible to supply a _link template_ which will then lead to mutation labels being clickable using
9
+ that link template.
10
+
11
+ The mutation link template can be (optionally) supplied to `gs-app` as a JSON object:
12
+
13
+ ```html
14
+ <gs-app
15
+ lapis="https://your.lapis.url"
16
+ mutationLinkTemplate='{
17
+ "nucleotideMutation": "https://cov-spectrum.org/explore/Switzerland/AllSamples/Past6M/variants?nucMutations={{mutation}}",
18
+ "aminoAcidMutation": "https://cov-spectrum.org/explore/Switzerland/AllSamples/Past6M/variants?aaMutations={{mutation}}",
19
+ }'
20
+ >
21
+ {/* children... */}
22
+ </gs-app>
23
+ ```
24
+
25
+ For example (like in the code above) you can directly link to cov-spectrum.
26
+
27
+ Your link needs to have the placeholder `{{mutation}}` in it, which will then be replaced with the mutation code.
@@ -3,10 +3,12 @@ import { customElement, property } from 'lit/decorators.js';
3
3
  import type { DetailedHTMLProps, HTMLAttributes } from 'react';
4
4
 
5
5
  import { MutationAnnotationsContextProvider } from '../../preact/MutationAnnotationsContext';
6
+ import { MutationLinkTemplateContextProvider } from '../../preact/MutationLinkTemplateContext';
6
7
  import { MutationComparison, type MutationComparisonProps } from '../../preact/mutationComparison/mutation-comparison';
7
8
  import { type Equals, type Expect } from '../../utils/typeAssertions';
8
9
  import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsStyles';
9
10
  import { type MutationAnnotations, mutationAnnotationsContext } from '../mutation-annotations-context';
11
+ import { type MutationLinkTemplate, mutationLinkTemplateContext } from '../mutation-link-template-context';
10
12
 
11
13
  /**
12
14
  * ## Context
@@ -103,17 +105,25 @@ export class MutationComparisonComponent extends PreactLitAdapterWithGridJsStyle
103
105
  @consume({ context: mutationAnnotationsContext, subscribe: true })
104
106
  mutationAnnotations: MutationAnnotations = [];
105
107
 
108
+ /**
109
+ * @internal
110
+ */
111
+ @consume({ context: mutationLinkTemplateContext, subscribe: true })
112
+ mutationLinkTemplate: MutationLinkTemplate = {};
113
+
106
114
  override render() {
107
115
  return (
108
116
  <MutationAnnotationsContextProvider value={this.mutationAnnotations}>
109
- <MutationComparison
110
- lapisFilters={this.lapisFilters}
111
- sequenceType={this.sequenceType}
112
- views={this.views}
113
- width={this.width}
114
- height={this.height}
115
- pageSize={this.pageSize}
116
- />
117
+ <MutationLinkTemplateContextProvider value={this.mutationLinkTemplate}>
118
+ <MutationComparison
119
+ lapisFilters={this.lapisFilters}
120
+ sequenceType={this.sequenceType}
121
+ views={this.views}
122
+ width={this.width}
123
+ height={this.height}
124
+ pageSize={this.pageSize}
125
+ />
126
+ </MutationLinkTemplateContextProvider>
117
127
  </MutationAnnotationsContextProvider>
118
128
  );
119
129
  }
@@ -89,9 +89,20 @@ const mutationAnnotations = [
89
89
  },
90
90
  ];
91
91
 
92
+ const mutationLinkTemplate = {
93
+ nucleotideMutation:
94
+ 'https://cov-spectrum.org/explore/Switzerland/AllSamples/Past6M/variants?nucMutations={{mutation}}',
95
+ aminoAcidMutation:
96
+ 'https://cov-spectrum.org/explore/Switzerland/AllSamples/Past6M/variants?aaMutations={{mutation}}',
97
+ };
98
+
92
99
  const Template: StoryObj<Required<MutationsOverTimeProps>> = {
93
100
  render: (args) => html`
94
- <gs-app lapis="${LAPIS_URL}" .mutationAnnotations=${mutationAnnotations}>
101
+ <gs-app
102
+ lapis="${LAPIS_URL}"
103
+ .mutationAnnotations=${mutationAnnotations}
104
+ .mutationLinkTemplate=${mutationLinkTemplate}
105
+ >
95
106
  <gs-mutations-over-time
96
107
  .lapisFilter=${args.lapisFilter}
97
108
  .sequenceType=${args.sequenceType}
@@ -3,9 +3,11 @@ import { customElement, property } from 'lit/decorators.js';
3
3
  import type { DetailedHTMLProps, HTMLAttributes } from 'react';
4
4
 
5
5
  import { MutationAnnotationsContextProvider } from '../../preact/MutationAnnotationsContext';
6
+ import { MutationLinkTemplateContextProvider } from '../../preact/MutationLinkTemplateContext';
6
7
  import { MutationsOverTime } from '../../preact/mutationsOverTime/mutations-over-time';
7
8
  import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsStyles';
8
9
  import { type MutationAnnotations, mutationAnnotationsContext } from '../mutation-annotations-context';
10
+ import { type MutationLinkTemplate, mutationLinkTemplateContext } from '../mutation-link-template-context';
9
11
 
10
12
  /**
11
13
  * ## Context
@@ -140,23 +142,31 @@ export class MutationsOverTimeComponent extends PreactLitAdapterWithGridJsStyles
140
142
  @consume({ context: mutationAnnotationsContext, subscribe: true })
141
143
  mutationAnnotations: MutationAnnotations = [];
142
144
 
145
+ /**
146
+ * @internal
147
+ */
148
+ @consume({ context: mutationLinkTemplateContext, subscribe: true })
149
+ mutationLinkTemplate: MutationLinkTemplate = {};
150
+
143
151
  override render() {
144
152
  return (
145
153
  <MutationAnnotationsContextProvider value={this.mutationAnnotations}>
146
- <MutationsOverTime
147
- lapisFilter={this.lapisFilter}
148
- sequenceType={this.sequenceType}
149
- views={this.views}
150
- width={this.width}
151
- height={this.height}
152
- granularity={this.granularity}
153
- lapisDateField={this.lapisDateField}
154
- displayMutations={this.displayMutations}
155
- initialMeanProportionInterval={this.initialMeanProportionInterval}
156
- hideGaps={this.hideGaps}
157
- useNewEndpoint={this.useNewEndpoint}
158
- pageSizes={this.pageSizes}
159
- />
154
+ <MutationLinkTemplateContextProvider value={this.mutationLinkTemplate}>
155
+ <MutationsOverTime
156
+ lapisFilter={this.lapisFilter}
157
+ sequenceType={this.sequenceType}
158
+ views={this.views}
159
+ width={this.width}
160
+ height={this.height}
161
+ granularity={this.granularity}
162
+ lapisDateField={this.lapisDateField}
163
+ displayMutations={this.displayMutations}
164
+ initialMeanProportionInterval={this.initialMeanProportionInterval}
165
+ hideGaps={this.hideGaps}
166
+ useNewEndpoint={this.useNewEndpoint}
167
+ pageSizes={this.pageSizes}
168
+ />
169
+ </MutationLinkTemplateContextProvider>
160
170
  </MutationAnnotationsContextProvider>
161
171
  );
162
172
  }
@@ -3,10 +3,12 @@ import { customElement, property } from 'lit/decorators.js';
3
3
  import type { DetailedHTMLProps, HTMLAttributes } from 'react';
4
4
 
5
5
  import { MutationAnnotationsContextProvider } from '../../preact/MutationAnnotationsContext';
6
+ import { MutationLinkTemplateContextProvider } from '../../preact/MutationLinkTemplateContext';
6
7
  import { Mutations, type MutationsProps } from '../../preact/mutations/mutations';
7
8
  import type { Equals, Expect } from '../../utils/typeAssertions';
8
9
  import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsStyles';
9
10
  import { type MutationAnnotations, mutationAnnotationsContext } from '../mutation-annotations-context';
11
+ import { type MutationLinkTemplate, mutationLinkTemplateContext } from '../mutation-link-template-context';
10
12
 
11
13
  /**
12
14
  * ## Context
@@ -134,18 +136,26 @@ export class MutationsComponent extends PreactLitAdapterWithGridJsStyles {
134
136
  @consume({ context: mutationAnnotationsContext, subscribe: true })
135
137
  mutationAnnotations: MutationAnnotations = [];
136
138
 
139
+ /**
140
+ * @internal
141
+ */
142
+ @consume({ context: mutationLinkTemplateContext, subscribe: true })
143
+ mutationLinkTemplate: MutationLinkTemplate = {};
144
+
137
145
  override render() {
138
146
  return (
139
147
  <MutationAnnotationsContextProvider value={this.mutationAnnotations}>
140
- <Mutations
141
- lapisFilter={this.lapisFilter}
142
- sequenceType={this.sequenceType}
143
- views={this.views}
144
- width={this.width}
145
- height={this.height}
146
- pageSize={this.pageSize}
147
- baselineLapisFilter={this.baselineLapisFilter}
148
- />
148
+ <MutationLinkTemplateContextProvider value={this.mutationLinkTemplate}>
149
+ <Mutations
150
+ lapisFilter={this.lapisFilter}
151
+ sequenceType={this.sequenceType}
152
+ views={this.views}
153
+ width={this.width}
154
+ height={this.height}
155
+ pageSize={this.pageSize}
156
+ baselineLapisFilter={this.baselineLapisFilter}
157
+ />
158
+ </MutationLinkTemplateContextProvider>
149
159
  </MutationAnnotationsContextProvider>
150
160
  );
151
161
  }
@@ -3,9 +3,11 @@ import { customElement, property } from 'lit/decorators.js';
3
3
  import { type DetailedHTMLProps, type HTMLAttributes } from 'react';
4
4
 
5
5
  import { MutationAnnotationsContextProvider } from '../../preact/MutationAnnotationsContext';
6
+ import { MutationLinkTemplateContextProvider } from '../../preact/MutationLinkTemplateContext';
6
7
  import { WastewaterMutationsOverTime } from '../../preact/wastewater/mutationsOverTime/wastewater-mutations-over-time';
7
8
  import { PreactLitAdapterWithGridJsStyles } from '../PreactLitAdapterWithGridJsStyles';
8
9
  import { type MutationAnnotations, mutationAnnotationsContext } from '../mutation-annotations-context';
10
+ import { type MutationLinkTemplate, mutationLinkTemplateContext } from '../mutation-link-template-context';
9
11
 
10
12
  /**
11
13
  * ## Context
@@ -79,16 +81,24 @@ export class WastewaterMutationsOverTimeComponent extends PreactLitAdapterWithGr
79
81
  @consume({ context: mutationAnnotationsContext, subscribe: true })
80
82
  mutationAnnotations: MutationAnnotations = [];
81
83
 
84
+ /**
85
+ * @internal
86
+ */
87
+ @consume({ context: mutationLinkTemplateContext, subscribe: true })
88
+ mutationLinkTemplate: MutationLinkTemplate = {};
89
+
82
90
  override render() {
83
91
  return (
84
92
  <MutationAnnotationsContextProvider value={this.mutationAnnotations}>
85
- <WastewaterMutationsOverTime
86
- lapisFilter={this.lapisFilter}
87
- sequenceType={this.sequenceType}
88
- width={this.width}
89
- height={this.height}
90
- pageSizes={this.pageSizes}
91
- />
93
+ <MutationLinkTemplateContextProvider value={this.mutationLinkTemplate}>
94
+ <WastewaterMutationsOverTime
95
+ lapisFilter={this.lapisFilter}
96
+ sequenceType={this.sequenceType}
97
+ width={this.width}
98
+ height={this.height}
99
+ pageSizes={this.pageSizes}
100
+ />
101
+ </MutationLinkTemplateContextProvider>
92
102
  </MutationAnnotationsContextProvider>
93
103
  );
94
104
  }