Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .docker/app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ ARG VUE_APP_API_URL=magic-api-url
ARG VUE_APP_LOGO_URL=magic-logo-url
ARG VUE_APP_HOMEPAGE_URL=magic-homepage-url
ARG VUE_APP_EDITABLE_INVENTORY=magic-setting
ARG VUE_APP_HIDE_COLLECTIONS=magic-hide-collections-setting
ARG VUE_APP_WEBSITE_TITLE=magic-title
ARG VUE_APP_QR_CODE_RESOLVER_URL=magic-qr-code-resolver-url
ARG VUE_APP_AUTOMATICALLY_GENERATE_ID_DEFAULT=magic-generate-id-setting
Expand Down
2 changes: 2 additions & 0 deletions .docker/app_entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ echo " LOGO_URL: ${VUE_APP_LOGO_URL}"
echo " LOGO_WIDTH: ${VUE_APP_LOGO_WIDTH}"
echo " HOMEPAGE_URL: ${VUE_APP_HOMEPAGE_URL}"
echo " EDITABLE_INVENTORY: ${VUE_APP_EDITABLE_INVENTORY}"
echo " HIDE_COLLECTIONS: ${VUE_APP_HIDE_COLLECTIONS}"
echo " WEBSITE_TITLE: ${VUE_APP_WEBSITE_TITLE}"
echo " QR_CODE_RESOLVER_URL: ${VUE_APP_QR_CODE_RESOLVER_URL}"
echo " AUTOMATICALLY_GENERATE_ID_DEFAULT: ${VUE_APP_AUTOMATICALLY_GENERATE_ID_DEFAULT}"
Expand All @@ -54,6 +55,7 @@ for file in $ROOT_DIR/js/app.*.js* $ROOT_DIR/*html; do
sed -i "s|magic-logo-width|${VUE_APP_LOGO_WIDTH}|g" $file
sed -i "s|magic-homepage-url|${VUE_APP_HOMEPAGE_URL}|g" $file
sed -i "s|magic-setting|${VUE_APP_EDITABLE_INVENTORY}|g" $file
sed -i "s|magic-hide-collections-setting|${VUE_APP_HIDE_COLLECTIONS}|g" $file
sed -i "s|magic-title|${VUE_APP_WEBSITE_TITLE}|g" $file
sed -i "s|magic-qr-code-resolver-url|${VUE_APP_QR_CODE_RESOLVER_URL}|g" $file
sed -i "s|magic-generate-id-setting|${VUE_APP_AUTOMATICALLY_GENERATE_ID_DEFAULT}|g" $file
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ services:
- VUE_APP_LOGO_URL
- VUE_APP_HOMEPAGE_URL
- VUE_APP_EDITABLE_INVENTORY
- VUE_APP_HIDE_COLLECTIONS
- VUE_APP_WEBSITE_TITLE
- VUE_APP_QR_CODE_RESOLVER_URL
- VUE_APP_AUTOMATICALLY_GENERATE_ID_DEFAULT
Expand Down Expand Up @@ -125,6 +126,7 @@ services:
environment:
- NODE_ENV=development
- VUE_APP_API_URL=${VUE_APP_API_URL:-http://localhost:5001}
- VUE_APP_HIDE_COLLECTIONS
- CHOKIDAR_USEPOLLING=true

networks:
Expand Down
1 change: 1 addition & 0 deletions pydatalab/docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ These can be provided as either:
- `VUE_APP_LOGO_URL`: the URL of an image to use as the logo header in the web app.
- `VUE_APP_HOMEPAGE_URL`: a URL to provide as a link from the web app header, and as a button on the dedicated login page.
- `VUE_APP_EDITABLE_INVENTORY`: whether the inventory can be edited by non-admin users in the web app.
- `VUE_APP_HIDE_COLLECTIONS`: whether to hide collection pages and controls in the web app. This defaults to `false`. It is not an access-control mechanism and does not disable collection API routes or alter stored collection data.
- `VUE_APP_WEBSITE_TITLE`: the title of the web app, which is displayed in the browser tab and header. It is also used in the heading of the dedicated login page, as "Welcome to the <title>".
- `VUE_APP_QR_CODE_RESOLVER_URL`: the URL of a service that can resolve QR codes to *datalab* entries, which is used by the web app to display QR codes for entries (see [datalab-org/datalab-purl](https://github.com/datalab-org/datalab-purl) for more information).
- `VUE_APP_AUTOMATICALLY_GENERATE_ID_DEFAULT`: whether to automatically generate IDs for new entries in the web app by default, or require a checkbox to be ticked at item creation.
Expand Down
9 changes: 9 additions & 0 deletions webapp/cypress/component/ItemGraphTest.cy.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,15 @@ describe("ItemGraph", () => {
cy.contains("configure").should("be.visible");
});

it("hides collection options when configured", () => {
mountGraph(twoConnectedNodes, { showOptions: true });
cy.then(() => {
Cypress.vueWrapper.vm.hideCollections = true;
return Cypress.vueWrapper.vm.$nextTick();
});
cy.contains("Ignore connections to collections:").should("not.exist");
});

it("hides options panel when showOptions is false", () => {
mountGraph(twoConnectedNodes, { showOptions: false });
cy.contains("configure").should("not.exist");
Expand Down
16 changes: 16 additions & 0 deletions webapp/cypress/component/NavbarTest.cy.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,22 @@ describe("Navbar", () => {
});
});

it("hides the collections navigation link when configured", () => {
cy.mount(Navbar, {
global: {
plugins: [store, router],
},
data() {
return { hideCollections: true };
},
});

cy.get("#nav").within(() => {
cy.contains("Collections").should("not.exist");
cy.contains("Inventory").should("have.attr", "href", "/starting-materials");
});
});

it("navigates to the correct route on link click", () => {
cy.mount(Navbar, {
global: {
Expand Down
24 changes: 24 additions & 0 deletions webapp/cypress/component/SampleTableTest.cy.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import "bootstrap/dist/css/bootstrap.css";
import DynamicDataTable from "@/components/DynamicDataTable.vue";
import DynamicDataTableButtons from "@/components/DynamicDataTableButtons.vue";
import SampleTable from "@/components/SampleTable.vue";
import UserBubble from "@/components/UserBubble.vue";
import StyledTooltip from "@/components/StyledTooltip.vue";
Expand Down Expand Up @@ -199,6 +200,29 @@ describe("SampleTable Component Tests", () => {
cy.get('[data-testid="search-input"]').should("exist");
});

it("hides collection table controls when configured", () => {
cy.then(() => {
const dataTable = wrapper.findComponent(DynamicDataTable);
dataTable.vm.hideCollections = true;
dataTable.vm.selectedColumns = dataTable.vm.availableColumns.filter((col) => !col.hidden);
dataTable.vm.itemsSelected = [store.state.sample_list[0]];

const buttons = dataTable.findComponent(DynamicDataTableButtons);
buttons.vm.hideCollections = true;

expect(dataTable.vm.availableColumns.some((col) => col.field === "collections")).to.be.false;
return dataTable.vm.$nextTick().then(() => {
expect(buttons.props("availableColumns").some((col) => col.field === "collections")).to.be
.false;
});
});

cy.get(".p-datatable-column-title").should("not.contain.text", "Collections");
cy.get('[data-testid="add-to-collection-button"]').should("not.exist");
cy.get('[data-testid="add-to-collection-form"]').should("not.exist");
cy.contains("Create new collection").should("not.exist");
});

it("closes table settings outside but keeps them open when selecting columns", () => {
cy.get('[data-testid="table-settings-button"]').click();
cy.get('[data-testid="table-settings-menu"]').should("be.visible");
Expand Down
6 changes: 4 additions & 2 deletions webapp/src/components/CreateItemModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@
<input id="create-item-name" v-model="name" type="text" class="form-control" />
</div>
</div>
<!-- All item types can be added to a collection, so this is always available -->
<div class="form-row">
<!-- When collections are visible, any item type can be added to a collection. -->
<div v-if="!hideCollections" class="form-row">
<div class="col-md-12 form-group">
<label id="startInCollection">(Optional) Insert into collection:</label>
<CollectionSelect
Expand Down Expand Up @@ -138,6 +138,7 @@ import {
SAMPLE_TABLE_TYPES,
INVENTORY_TYPES,
AUTOMATICALLY_GENERATE_ID_DEFAULT,
HIDE_COLLECTIONS,
} from "@/resources.js";
import CollectionSelect from "@/components/CollectionSelect.vue";
export default {
Expand Down Expand Up @@ -169,6 +170,7 @@ export default {
selectedItemToCopy: null,
startingConstituents: [],
generateIDAutomatically: AUTOMATICALLY_GENERATE_ID_DEFAULT,
hideCollections: HIDE_COLLECTIONS,
agesAgo: new Date("1970-01-01").toISOString().slice(0, -8), // a datetime for the unix epoch start
shareWithGroups: [],
additionalCreators: [],
Expand Down
10 changes: 7 additions & 3 deletions webapp/src/components/DynamicDataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,10 @@
/>
<BatchCreateItemModal v-model="batchCreateItemModalIsOpen" />
<QRScannerModal v-model="qrScannerModalIsOpen" />
<CreateCollectionModal v-model="createCollectionModalIsOpen" />
<CreateCollectionModal v-if="!hideCollections" v-model="createCollectionModalIsOpen" />
<CreateEquipmentModal v-model="createEquipmentModalIsOpen" />
<AddToCollectionModal
v-if="!hideCollections"
v-model="addToCollectionModalIsOpen"
:items-selected="itemsSelected"
@items-updated="handleItemsUpdated"
Expand All @@ -167,7 +168,7 @@ import CreateEquipmentModal from "@/components/CreateEquipmentModal";
import AddToCollectionModal from "@/components/AddToCollectionModal";
import BatchShareModal from "@/components/BatchShareModal";

import { INVENTORY_TABLE_TYPES, EDITABLE_INVENTORY } from "@/resources.js";
import { INVENTORY_TABLE_TYPES, EDITABLE_INVENTORY, HIDE_COLLECTIONS } from "@/resources.js";

import { FilterMatchMode, FilterOperator, FilterService } from "@primevue/core/api";
import DataTable from "primevue/datatable";
Expand Down Expand Up @@ -254,6 +255,7 @@ export default {
filteredData: [],
allowedTypes: INVENTORY_TABLE_TYPES,
editable_inventory: EDITABLE_INVENTORY,
hideCollections: HIDE_COLLECTIONS,
selectedColumns: [],
// Names of the per-column matchers this instance registered with the global
// FilterService, so that they can be removed again when it unmounts.
Expand Down Expand Up @@ -302,7 +304,9 @@ export default {
);
},
availableColumns() {
return this.columns.map((col) => ({ ...col }));
return this.columns
.filter((col) => !this.hideCollections || col.field !== "collections")
.map((col) => ({ ...col }));
},
},
created() {
Expand Down
7 changes: 5 additions & 2 deletions webapp/src/components/DynamicDataTableButtons.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
</button>
</template>
<button
v-if="dataType === 'collections'"
v-if="!hideCollections && dataType === 'collections'"
data-testid="add-collection-button"
class="btn btn-default btn-action"
@click="$emit('open-create-collection-modal')"
Expand Down Expand Up @@ -162,6 +162,7 @@
>
<a
v-if="
!hideCollections &&
!['collections', 'collectionItems', 'users', 'tokens', 'groups', 'tags'].includes(
dataType,
)
Expand All @@ -173,7 +174,7 @@
Add to collection
</a>
<a
v-if="dataType === 'collectionItems'"
v-if="!hideCollections && dataType === 'collectionItems'"
data-testid="remove-from-collection-dropdown"
class="dropdown-item"
@click="confirmRemoveFromCollection"
Expand Down Expand Up @@ -366,6 +367,7 @@ import { vOnClickOutside } from "@vueuse/components";
import BulkChangeRoleModal from "@/components/BulkChangeRoleModal.vue";
import BulkAddToGroupModal from "@/components/BulkAddToGroupModal.vue";
import BulkChangeManagersModal from "@/components/BulkChangeManagersModal.vue";
import { HIDE_COLLECTIONS } from "@/resources.js";

import {
deleteSample,
Expand Down Expand Up @@ -473,6 +475,7 @@ export default {
showBulkChangeRoleModal: false,
showBulkAddToGroupModal: false,
showBulkChangeManagersModal: false,
hideCollections: HIDE_COLLECTIONS,
};
},
computed: {
Expand Down
4 changes: 3 additions & 1 deletion webapp/src/components/EquipmentInformation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
:possible-item-statuses="possibleItemStatuses"
/>
</div>
<div class="form-group col-md-3 col-sm-3">
<div v-if="!hideCollections" class="form-group col-md-3 col-sm-3">
<label id="collections" class="mr-2">Collections</label>
<div>
<CollectionList aria-labelledby="collections" :collections="Collections" />
Expand Down Expand Up @@ -99,6 +99,7 @@ import ToggleableCreatorsFormGroup from "@/components/ToggleableCreatorsFormGrou
import ToggleableItemStatusFormGroup from "@/components/ToggleableItemStatusFormGroup";
import ToggleableGroupsFormGroup from "@/components/ToggleableGroupsFormGroup";
import ToggleableTagsFormGroup from "@/components/ToggleableTagsFormGroup";
import { HIDE_COLLECTIONS } from "@/resources.js";

export default {
components: {
Expand All @@ -118,6 +119,7 @@ export default {
},
data() {
return {
hideCollections: HIDE_COLLECTIONS,
tableOfContentsSections: [
{ title: "Equipment Information", targetID: "equipment-information" },
{ title: "Table of Contents", targetID: "table-of-contents" },
Expand Down
21 changes: 12 additions & 9 deletions webapp/src/components/ItemGraph.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,16 @@
@option:deselected="readdItemToGraph"
/>

<label for="ignore-collections">Ignore connections to collections:</label>
<CollectionSelect
id="ignore-collections"
v-model="ignoreCollections"
multiple
@option:selected="removeItemFromGraph"
@option:deselected="readdItemToGraph"
/>
<template v-if="!hideCollections">
<label for="ignore-collections">Ignore connections to collections:</label>
<CollectionSelect
id="ignore-collections"
v-model="ignoreCollections"
multiple
@option:selected="removeItemFromGraph"
@option:deselected="readdItemToGraph"
/>
</template>

<div class="form-group form-check mt-3">
<input
Expand Down Expand Up @@ -120,7 +122,7 @@
<script>
import ItemSelect from "@/components/ItemSelect.vue";
import CollectionSelect from "@/components/CollectionSelect.vue";
import { itemTypes } from "@/resources.js";
import { itemTypes, HIDE_COLLECTIONS } from "@/resources.js";
import cytoscape from "cytoscape";
import cola from "cytoscape-cola";
import elk from "cytoscape-elk";
Expand Down Expand Up @@ -215,6 +217,7 @@ export default {
ignoreItems: [],
removedNodeData: {},
ignoreCollections: [],
hideCollections: HIDE_COLLECTIONS,
labelStartingMaterialsByName: true,
labelItemsByName: false,
showBlocks: this.defaultShowBlocks,
Expand Down
7 changes: 5 additions & 2 deletions webapp/src/components/Navbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
<div id="nav" data-testid="navbar-navigation">
<router-link to="/about">About</router-link> |
<router-link to="/samples">Samples</router-link> |
<router-link to="/collections">Collections</router-link> |
<template v-if="!hideCollections">
<router-link to="/collections">Collections</router-link> |
</template>
<router-link to="/starting-materials">Inventory</router-link> |
<router-link to="/equipment">Equipment</router-link> |
<router-link to="/item-graph"
Expand Down Expand Up @@ -48,7 +50,7 @@
</template>

<script>
import { API_URL, LOGO_URL, LOGO_WIDTH, HOMEPAGE_URL } from "@/resources.js";
import { API_URL, LOGO_URL, LOGO_WIDTH, HOMEPAGE_URL, HIDE_COLLECTIONS } from "@/resources.js";
import LoginDetails from "@/components/LoginDetails.vue";

export default {
Expand All @@ -62,6 +64,7 @@ export default {
logo_url: LOGO_URL,
logo_width: LOGO_WIDTH,
homepage_url: HOMEPAGE_URL,
hideCollections: HIDE_COLLECTIONS,
user: null,
};
},
Expand Down
4 changes: 3 additions & 1 deletion webapp/src/components/SampleGraphExportModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
</label>
</div>
<hr />
<div class="form-check">
<div v-if="!hideCollections" class="form-check">
<input
id="create-collection"
v-model="createCollection"
Expand Down Expand Up @@ -164,6 +164,7 @@ import ExportProgressModal from "@/components/ExportProgressModal";

import { startItemExport, createNewCollection, getItemGraph } from "@/server_fetch_utils";
import { DialogService } from "@/services/DialogService";
import { HIDE_COLLECTIONS } from "@/resources.js";

export default {
name: "SampleGraphExportModal",
Expand All @@ -187,6 +188,7 @@ export default {
selectedSampleIds: [],
selectAll: false,
createCollection: false,
hideCollections: HIDE_COLLECTIONS,
collectionId: "",
collectionTitle: "",
graphDepth: 1,
Expand Down
3 changes: 3 additions & 0 deletions webapp/src/components/ToggleableCollectionFormGroup.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<div
v-if="!hideCollections"
ref="outerdiv"
class="h-100 form-group clickable"
@click="isEditingCollections = !isEditingCollections"
Expand Down Expand Up @@ -42,6 +43,7 @@
import CollectionSelect from "@/components/CollectionSelect";
import CollectionList from "@/components/CollectionList";
import { OnClickOutside } from "@vueuse/components";
import { HIDE_COLLECTIONS } from "@/resources.js";

export default {
components: {
Expand All @@ -60,6 +62,7 @@ export default {
return {
isEditingCollections: false,
outerDivRef: null,
hideCollections: HIDE_COLLECTIONS,
};
},
computed: {
Expand Down
3 changes: 3 additions & 0 deletions webapp/src/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export const GRAVATAR_STYLE = "identicon";
const editable_inventory = process.env.VUE_APP_EDITABLE_INVENTORY || "false";
export const EDITABLE_INVENTORY = editable_inventory.toLowerCase() == "true";

const hide_collections = process.env.VUE_APP_HIDE_COLLECTIONS || "false";
export const HIDE_COLLECTIONS = hide_collections.toLowerCase() == "true";

const automatically_generate_id_default =
process.env.VUE_APP_AUTOMATICALLY_GENERATE_ID_DEFAULT || "false";
export const AUTOMATICALLY_GENERATE_ID_DEFAULT =
Expand Down
Loading
Loading