Skip to content

Commit fba01ad

Browse files
authored
Merge pull request #1 from gecage952/dev
merge dev into branch
2 parents 6dfbc7a + abbb03c commit fba01ad

488 files changed

Lines changed: 12528 additions & 8055 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.ci/ignore-spelling.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
hda
2+
implementors

.github/labeler.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ area/toolshed:
6363
- lib/toolshed/**/*
6464
- templates/webapps/tool_shed/**/*
6565
area/UI-UX:
66-
- all: ["client/src/**/*", "!client/src/schema/schema.ts"]
66+
- all: ["client/src/**/*", "!client/src/api/schema/schema.ts"]
6767
any: ["templates/**/*"]
6868
area/util:
6969
- lib/galaxy/util/**/*

.github/workflows/lint.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ jobs:
2020
name: Test
2121
runs-on: ubuntu-latest
2222
strategy:
23+
fail-fast: false
2324
matrix:
2425
python-version: ['3.7', '3.11']
2526
env:

.github/workflows/lint_openapi_schema.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
- name: Check for changes
5858
run: |
5959
if [[ `git status --porcelain` ]]; then
60-
echo "Rebuilding client/src/schema/schema.ts resulted in changes, run 'make update-client-api-schema' and commit results"
60+
echo "Rebuilding client/src/api/schema/schema.ts resulted in changes, run 'make update-client-api-schema' and commit results"
6161
exit 1
6262
fi
6363
working-directory: 'galaxy root'

.github/workflows/toolshed.yaml

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,11 @@ jobs:
1919
name: Test
2020
runs-on: ubuntu-latest
2121
strategy:
22+
fail-fast: false
2223
matrix:
23-
include:
24-
- test-install-client: 'galaxy_api'
25-
python-version: '3.7'
26-
shed-api: 'v1'
27-
shed-browser: 'twill'
28-
- test-install-client: 'standalone'
29-
python-version: '3.8'
30-
shed-api: 'v1'
31-
shed-browser: 'twill'
32-
- test-install-client: 'galaxy_api'
33-
python-version: '3.9'
34-
shed-api: 'v2'
35-
shed-browser: 'playwright'
36-
- test-install-client: 'standalone'
37-
python-version: '3.10'
38-
shed-api: 'v2'
39-
shed-browser: 'playwright'
24+
python-version: ['3.7', '3.11']
25+
shed-api: ['v1', 'v2']
26+
test-install-client: ['galaxy_api', 'standalone']
4027
services:
4128
postgres:
4229
image: postgres:13
@@ -50,6 +37,11 @@ jobs:
5037
- uses: actions/checkout@v3
5138
with:
5239
path: 'galaxy root'
40+
- uses: actions/setup-node@v3
41+
with:
42+
node-version: '18.12.1'
43+
cache: 'yarn'
44+
cache-dependency-path: 'galaxy root/client/yarn.lock'
5345
- uses: actions/setup-python@v4
5446
with:
5547
python-version: ${{ matrix.python-version }}
@@ -68,25 +60,30 @@ jobs:
6860
with:
6961
path: 'galaxy root/.venv'
7062
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-toolshed
71-
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy_root/requirements.txt') }}-toolshed
7263
- name: Install dependencies
7364
run: ./scripts/common_startup.sh --skip-client-build
7465
working-directory: 'galaxy root'
7566
- name: Build Frontend
76-
run: '. .venv/bin/activate && cd lib/tool_shed/webapp/frontend && yarn && make client'
67+
run: |
68+
. .venv/bin/activate
69+
cd lib/tool_shed/webapp/frontend
70+
yarn
71+
make client
7772
working-directory: 'galaxy root'
7873
- name: Install playwright
79-
run: '. .venv/bin/activate && playwright install'
74+
run: |
75+
. .venv/bin/activate
76+
playwright install
8077
working-directory: 'galaxy root'
8178
- name: Run tests
82-
run: './run_tests.sh -toolshed'
79+
run: ./run_tests.sh -toolshed
8380
env:
8481
TOOL_SHED_TEST_INSTALL_CLIENT: ${{ matrix.test-install-client }}
8582
TOOL_SHED_API_VERSION: ${{ matrix.shed-api }}
86-
TOOL_SHED_TEST_BROWSER: ${{ matrix.shed-browser }}
83+
TOOL_SHED_TEST_BROWSER: ${{ matrix.shed-api == 'v1' && 'twill' || 'playwright' }}
8784
working-directory: 'galaxy root'
8885
- uses: actions/upload-artifact@v3
8986
if: failure()
9087
with:
91-
name: Toolshed test results (${{ matrix.python-version }}, ${{ matrix.test-install-client }})
88+
name: Toolshed test results (${{ matrix.python-version }}, ${{ matrix.shed-api }}, ${{ matrix.test-install-client }})
9289
path: 'galaxy root/run_toolshed_tests.html'

.k8s_ci.Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ RUN set -xe; \
166166

167167
# Create Galaxy user, group, directory; chown
168168
RUN set -xe; \
169-
adduser --system --group $GALAXY_USER \
169+
adduser --system --group --uid 101 $GALAXY_USER \
170170
&& mkdir -p $SERVER_DIR \
171171
&& chown $GALAXY_USER:$GALAXY_USER $ROOT_DIR -R
172172

@@ -179,7 +179,8 @@ COPY --chown=$GALAXY_USER:$GALAXY_USER --from=client_build $SERVER_DIR/static ./
179179
WORKDIR $SERVER_DIR
180180

181181
# The data in version.json will be displayed in Galaxy's /api/version endpoint
182-
RUN printf "{\n \"git_commit\": \"$(cat GITREVISION)\",\n \"build_date\": \"$BUILD_DATE\",\n \"image_tag\": \"$IMAGE_TAG\"\n}\n" > version.json
182+
RUN printf "{\n \"git_commit\": \"$(cat GITREVISION)\",\n \"build_date\": \"$BUILD_DATE\",\n \"image_tag\": \"$IMAGE_TAG\"\n}\n" > version.json \
183+
&& chown $GALAXY_USER:$GALAXY_USER version.json
183184

184185
EXPOSE 8080
185186
USER $GALAXY_USER

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ remove-api-schema:
189189
rm _shed_schema.yaml
190190

191191
update-client-api-schema: client-node-deps build-api-schema
192-
$(IN_VENV) cd client && node openapi_to_schema.mjs ../_schema.yaml > src/schema/schema.ts && npx prettier --write src/schema/schema.ts
192+
$(IN_VENV) cd client && node openapi_to_schema.mjs ../_schema.yaml > src/api/schema/schema.ts && npx prettier --write src/api/schema/schema.ts
193193
$(IN_VENV) cd client && node openapi_to_schema.mjs ../_shed_schema.yaml > ../lib/tool_shed/webapp/frontend/src/schema/schema.ts && npx prettier --write ../lib/tool_shed/webapp/frontend/src/schema/schema.ts
194194
$(MAKE) remove-api-schema
195195

client/.eslintrc.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,14 @@ const baseRules = {
4141
"vuejs-accessibility/form-control-has-label": "warn",
4242
"vuejs-accessibility/heading-has-content": "error",
4343
"vuejs-accessibility/iframe-has-title": "error",
44-
"vuejs-accessibility/label-has-for": "warn",
44+
"vuejs-accessibility/label-has-for": [
45+
"warn",
46+
{
47+
required: {
48+
some: ["nesting", "id"],
49+
},
50+
},
51+
],
4552
"vuejs-accessibility/mouse-events-have-key-events": "warn",
4653
"vuejs-accessibility/no-autofocus": "error",
4754
"vuejs-accessibility/no-static-element-interactions": "warn",
@@ -117,21 +124,23 @@ module.exports = {
117124
files: ["**/*.ts", "**/*.tsx"],
118125
extends: [
119126
...baseExtends,
120-
"plugin:@typescript-eslint/eslint-recommended",
121127
"plugin:@typescript-eslint/recommended",
128+
// "plugin:@typescript-eslint/stylistic" // TODO: work towards this
122129
],
123130
rules: {
124131
...baseRules,
125132
"@typescript-eslint/no-throw-literal": "error",
126133
"@typescript-eslint/ban-ts-comment": "warn",
134+
"@typescript-eslint/no-explicit-any": "warn", // TODO: re-enable this
135+
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "_.+", varsIgnorePattern: "_.+" }],
127136
},
128137
parser: "@typescript-eslint/parser",
129138
parserOptions: {
130139
ecmaFeatures: { jsx: true },
131140
ecmaVersion: 2020,
132141
sourceType: "module",
133142
extraFileExtensions: [".vue"],
134-
project: "./tsconfig.json",
143+
project: true,
135144
},
136145
plugins: [...basePlugins, "@typescript-eslint"],
137146
},

client/docs/querying-the-api.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Best practices when querying the API from UI components
2+
3+
If you need to query the API from a component, there are several ways to do so. This document will help you decide which one to use and provide some best practices when doing so to keep the code clean and maintainable.
4+
5+
## Choose the Right Approach
6+
7+
When querying APIs in Vue components, consider the following approaches and their best practices:
8+
9+
## 1. Prefer Composables over Stores over Direct API Calls
10+
11+
### Composables
12+
13+
- **What Are Composables?**: please read the official Vue documentation on composables [here](https://vuejs.org/guide/reusability/composables.html).
14+
15+
If there is already a composable that takes care of the logic you need for accessing a particular resource in the API please use it or consider writing a new one. They provide a type-safe interface and a higher level of abstraction than the related Store or the API itself. They might rely on one or more Stores for caching and reactivity.
16+
17+
### Stores
18+
19+
- **Stores Explained**: Please read the official Vue documentation on State Management [here](https://vuejs.org/guide/scaling-up/state-management.html).
20+
21+
If there is no Composable for the API endpoint you are using, try using a (Pinia) Store instead. Stores are type-safe and provide a reactive interface to the API. They can also be used to cache data, ensuring a single source of truth.
22+
23+
- **Use Pinia Stores**: If you need to create a new Store, make sure to create a Pinia Store, and not a Vuex Store as Pinia will be the replacement for Vuex. Also, use [Composition API syntax over the Options API](https://vuejs.org/guide/extras/composition-api-faq.html) for increased readability, code organization, type inference, etc.
24+
25+
### Direct API Calls
26+
27+
- If the type of data you are querying should not be cached, or you just need to update or create new data, you can use the API directly. Make sure to use the **Fetcher** (see below) instead of Axios, as it provides a type-safe interface to the API along with some extra benefits.
28+
29+
## 2. Prefer Fetcher over Axios (when possible)
30+
31+
- **Use Fetcher with OpenAPI Specs**: If there is an OpenAPI spec for the API endpoint you are using (in other words, there is a FastAPI route defined in Galaxy), always use the Fetcher. It will provide you with a type-safe interface to the API.
32+
33+
**Do**
34+
35+
```typescript
36+
import { fetcher } from "@/api/schema";
37+
const datasetsFetcher = fetcher.path("/api/dataset/{id}").method("get").create();
38+
39+
const { data: dataset } = await datasetsFetcher({ id: "testID" });
40+
```
41+
42+
**Don't**
43+
44+
```js
45+
import axios from "axios";
46+
import { getAppRoot } from "onload/loadConfig";
47+
import { rethrowSimple } from "utils/simple-error";
48+
49+
async getDataset(datasetId) {
50+
const url = `${getAppRoot()}api/datasets/${datasetId}`;
51+
try {
52+
const response = await axios.get(url);
53+
return response.data;
54+
} catch (e) {
55+
rethrowSimple(e);
56+
}
57+
}
58+
59+
const dataset = await getDataset("testID");
60+
```
61+
62+
> **Reason**
63+
>
64+
> The `fetcher` class provides a type-safe interface to the API, and is already configured to use the correct base URL and error handling.
65+
66+
## 3. Where to put your API queries?
67+
68+
The short answer is: **it depends**. There are several factors to consider when deciding where to put your API queries:
69+
70+
### Is the data you are querying related exclusively to a particular component?
71+
72+
If so, you should put the query in the component itself. If not, you should consider putting it in a Composable or a Store.
73+
74+
### Can the data be cached?
75+
76+
If so, you should consider putting the query in a Store. If not, you should consider putting it in a Composable or the component itself.
77+
78+
### Is the query going to be used in more than one place?
79+
80+
If so, you should consider putting it under src/api/<resource>.ts and exporting it from there. This will allow you to reuse the query in multiple places specially if you need to do some extra processing of the data. Also it will help to keep track of what parts of the API are being used and where.
81+
82+
### Should I use the `fetcher` directly or should I write a wrapper function?
83+
84+
- If you **don't need to do any extra processing** of the data, you can use the `fetcher` directly.
85+
- If you **need to do some extra processing**, you should consider writing a wrapper function. Extra processing can be anything from transforming the data to adding extra parameters to the query or omitting some of them, handling conditional types in response data, etc.
86+
- Using a **wrapper function** will help in case we decide to replace the `fetcher` with something else in the future (as we are doing now with _Axios_).

0 commit comments

Comments
 (0)