mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 01:33:33 +00:00
[EC-14] Part II: Add Collection Rows to Vault List (#3875)
* [EC-14] initial refactoring of vault filter * [EC-14] return observable trees for all filters with head node * [EC-14] Remove bindings on callbacks * [EC-14] fix formatting on disabled orgs * [EC-14] hide MyVault if personal org policy * [EC-14] add check for single org policy * [EC-14] add policies to org and change node constructor * [EC-14] don't show options if personal vault policy * [EC-14] default to all vaults * [EC-14] add default selection to filters * [EC-14] finish filter model callbacks * [EC-14] finish filter functionality and begin cleaning up * [EC-14] clean up old components and start on org vault * [EC-14] loop through filters for presentation * [EC-14] refactor VaultFilterService and put filter presentation data back into Vault Filter component. Remove VaultService * [EC-14] begin refactoring org vault * [EC-14] Refactor Vault Filter Service to use observables * [EC-14] finish org vault filter * [EC-14] fix vault model tests * [EC-14] fix org service calls * [EC-14] pull refactor out of shared code * [EC-14] include head node for collections even if collections aren't loaded yet * [EC-14] fix url params for vaults * [EC-14] remove comments * [EC-14] Remove unnecesary getter for org on vault filter * [EC-14] fix linter * [EC-14] fix prettier * [EC-14] add deprecated methods to collection service for desktop and browser * [EC-14] simplify cipher type node check * [EC-14] add getters to vault filter model * [EC-14] refactor how we build the filter list into methods * [EC-14] add getters to build filter method * [EC-14] start adding header and collection rows * [EC-14] remove param ids if false * [EC-14] Make collection rows navigatable * [EC-14] fix collapsing nodes * [EC-14] add specific type to search placeholder * [EC-14] remove extra constructor and comment from org vault filter * [EC-14] extract subscription callback to methods * [EC-14] Remove unecessary await * [EC-14] Remove ternary operators while building org filter * [EC-14] remove unnecessary deps array in vault filter service declaration * [EC-14] consolidate new models into one file * [EC-14] change name of edit collections method * [EC-14] add collection badges to item rows * [EC-14] show groups badge on collection rows * [EC-14] add bulk actions to header menu button * [EC-14] initialize nested observable inside of service Signed-off-by: Jacob Fink <jfink@bitwarden.com> * [EC-14] change how we load orgs into the vault filter and select the default filter * [EC-14] remove get from getters name * [EC-14] remove eslint-disable comment * [EC-14] move vault filter service abstraction to angular folder and separate * [EC-14] rename filter types and delete VaultFilterLabel * [EC-14] remove changes to workspace file * [EC-14] remove deprecated service from jslib module * [EC-14] remove any remaining files from common code * [EC-14] consolidate vault filter components into components folder * [EC-14] simplify method call * [EC-14] refactor the vault filter service - orgs now have observable property - BehaviorSubjects have been migrated to ReplaySubjects if they don't need starting value - added unit tests - fix small error when selecting org badge of personal vault - renamed some properties * [EC-14] replace mergeMap with switchMap in vault filter service * [EC-14] early return to prevent nesting * [EC-14] clean up filterCollections method * [EC-14] use isDeleted helper in html * [EC-14] add jsdoc comments to ServiceUtils * [EC-14] fix linter * [EC-14] use array.slice instead of setting length * [EC-14] resolve merge conflicts * [EC-14] remove checkbox from end user vault collection rows * [EC-14] add owner column to collections in end user vault * [EC-14] add a11y titles for vault filters * Update apps/web/src/app/vault/vault-filter/services/vault-filter.service.ts Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> * [EC-14] add missing high level jsdoc description * [EC-14] fix storybook absolute imports * [EC-14] delete vault-shared.module * [EC-14] change search placeholder text to getter and add missing strings * [EC-14] remove two way binding from search text in vault filter * [EC-14] removed all binding from search text and just use input event * [EC-14] remove async from apply vault filter * [EC-14] remove circular observable calls in vault filter service Co-authored-by: Thomas Rittson <eliykat@users.noreply.github.com> * [EC-14] move collapsed nodes to vault filter section * [EC-14] deconstruct filter section inside component * [EC-14] fix merge conflicts and introduce refactored organization service to vault filter service * [EC-14] remove mutation from filter builders * [EC-14] fix styling on buildFolderTree * [EC-14] remove leftover folder-filters reference and use ternary for collapse icon * [EC-14] remove unecessary checks * [EC-14] stop rebuilding filters when the organization changes * [EC-14] Move subscription out of setter in vault filter section * [EC-14] remove extra policy service methods from vault filter service * [EC-14] remove new methods from old vault-filter.service * [EC-14] Use vault filter service in vault components * [EC-14] reload collections from vault now that we have vault filter service * [EC-14] remove currentFilterCollections in vault filter component * [EC-14] change VaultFilterType to more specific OrganizationFilter in organization-options * [EC-14] include org check in isNodeSelected * [EC-14] add getters to filter function, fix storybook, and add test for All Collections * [EC-14] Resolve merge conflicts * [EC-14] fix merge conflicts * [EC-14] fix merge conflicts: org service protected and remove absolute path * [EC-14] separate org vault filter service observables * [EC-14] remove folder subject in vault filter service * [EC-14] remove collections subject from vault filter service * [EC-14] change collection api call name - getCollectionsWithDetails to getManyCollectionsWithDetails * [EC-14] add collection functionality - add endpoint to bulk delete collections - add logic to bulk delete both ciphers and collections - refresh ciphers list after making collection changes - stop making api calls from ciphers list each time a filter changes * [EC-14] get collections from vault filter service - for badge, instead of passing through @Input variable * [EC-14] only bulk delete collections if passed * [EC-14] fix deleting ciphers in org vault - reuse same logic from end user vault - call different api endpoints * [EC-14] include collections in MaxCheckedCount * [EC-14] add paging to collections * [EC-14] hide collections if searching * [EC-14] change vault table to new table component - removed a lot of scss classes to use tailwind alternatives - added getters for arrays in component that template can reference - imported and used new bitIconButton for options button * [EC-14] remove cursor pointer when checkbox not available * [EC-14] stop reloading cipher list too early * [EC-14] stop setting cipher component to loaded too early - loaded variable on cipher component hides the loaded indicator - when setting the default filter, we were triggering that variable - instead, we'll just set the active filter and let it grab the filter when ready * [EC-14] check/navigate collection when clicked * [EC-14] rename edit collections callback - used to be onEditCollection - renamed to onEditCipherCollections * [EC-14] remove showOrganizationBadge property - property used to tell template whether it was org vault or end user - replace with check for organization property * [EC-14] replace || with ?? in load function of ciphers * [EC-14] remove nested subscriptions - nested subscriptions = bad - the only dependency any of the subscriptions have is on the organization - use withLatestFrom to verify that the org has been set before firing * [EC-14] add getters and rename method * [EC-14] add null check in bulk delete component - some input variables can be null, so we can't just check the length * [EC-14] add ItemRow type - ItemRow can be either CipherView or CollectionFilter - Consolidated a large portion of selection logic * [EC-14] remove extra applyFilter override - Removed extra applyFIlter, allCiphers has already been filtered by org - Also reordered some of the methods to make more sense * [EC-14] remove extra collections uncheck * [EC-14] transition bulk delete to dialog service * [EC-14] transition bulk restore to dialog service * [EC-14] transition bulk move to dialog service * [EC-14] transition bulk share to dialog service * [EC-14] remove modal references * [EC-14] reload cipher list when changing orgs * [EC-14] add helper method to bulk delete dialog - Gives us built in typing instead of having to redeclare * [EC-14] add helper to open bulk restore dialog - Gives us typing without redeclaring * [EC-14] add open helper to bulk move dialog * [EC-14] add open helper to bulk share dialog - Adds typing to data - also removed the component refs from bulk actions * [EC-14] remove modal service from bulk actions * [EC-14] introduce VaultItemRow to combine cipher and collections * [EC-14] show loading indicator while switching orgs * [EC-14] remove indexing every time filter changes - also reverted back to using setter for changing org * [EC-14] allow searching by function in search pipe - this allows us to search parent properties in objects Co-authored-by: Andreas Coroiu <andreas@andreascoroiu.com> * [EC-14] make collections searchable - used search pipe to filter based on search text * [EC-14] consolidate bulk dialogs in single module * [EC-14] remove form promise from bulk dialogs * [EC-14] stop casting dialog return type - we now have a helper function that gives us typing on result * [EC-14] add length check to array guard * [EC-14] remove extra false assignment * [EC-14] move to sentence case * [EC-14] address pr feedback * [EC-14] add back the default assignment to deleted - we need this default assignment to check for null or undefined values * [EC-14] remove optional chaining - everything is initialized to an empty array so it should never be null * [EC-14] remove manager check to show org vault - this is fixed upstream in a more comprehensive way * [EC-686] add tests and comments to serviceUtils (#4092) * [EC-686] add tests and comments to serviceUtls * [EC-686] whitelist spec filename from linter * [EC-686] fix prettier * [EC-14] use new collection admin service * [EC-14] fix groups searching * [EC-14] use new groups service and models * [EC-14] fix shared module * [EC-14] remove leftover empty vault filter service * [EC-14] remove CollectionGroupDetailsView models * [EC-14] replace GroupDetails with AdminView - Collections in vault filter now use admin view to get access details - Collections shown in cipher list use admin view for access details * [EC-14] add back the dialog to shared module * [EC-14] hide org vault if lacking permissions * [EC-14] add edit collection dialog to vault * [EC-14] add screen reader label to share dialog * [EC-14] moved sync call below subscription - the subscription gives a callback for when we finish a sync - by awaiting the sync before we weren't using the callback to refresh * [EC-14] move cipher params check to switchMap - we want to avoid async subscriptions * [EC-14] clean up subscriptions in org vault - added takeUntil - use combineLatest * [EC-14] clean up vault subscriptions - remove nested subscriptions - use takeUntil * [EC-14] init ciphers component first * [EC-14] fix view vault tab permissions - CanViewAssignedCollections doesn't include CanViewAllCollections - CanViewAssignedCollections does include IsManager * [EC-14] reduce nesting * [EC-14] rename bulk action dialogs selectors * [EC-14] fix permissions for collection management - users with custom admin permissions should be able to edit as well * [EC-14] prettier * [EC-14] use percentages for table columns widths * [EC-14] use GetCollectionAccessDetails in cli - renamed api call Signed-off-by: Jacob Fink <jfink@bitwarden.com> Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Co-authored-by: Thomas Rittson <eliykat@users.noreply.github.com> Co-authored-by: Andreas Coroiu <andreas@andreascoroiu.com>
This commit is contained in:
@@ -14,7 +14,6 @@ export class VaultItemsComponent {
|
||||
|
||||
loaded = false;
|
||||
ciphers: CipherView[] = [];
|
||||
searchText: string;
|
||||
searchPlaceholder: string = null;
|
||||
filter: (cipher: CipherView) => boolean = null;
|
||||
deleted = false;
|
||||
@@ -24,11 +23,18 @@ export class VaultItemsComponent {
|
||||
protected searchPending = false;
|
||||
|
||||
private searchTimeout: any = null;
|
||||
private _searchText: string = null;
|
||||
get searchText() {
|
||||
return this._searchText;
|
||||
}
|
||||
set searchText(value: string) {
|
||||
this._searchText = value;
|
||||
}
|
||||
|
||||
constructor(protected searchService: SearchService) {}
|
||||
|
||||
async load(filter: (cipher: CipherView) => boolean = null, deleted = false) {
|
||||
this.deleted = deleted || false;
|
||||
this.deleted = deleted ?? false;
|
||||
await this.applyFilter(filter);
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
import { Pipe, PipeTransform } from "@angular/core";
|
||||
|
||||
type PropertyValueFunction<T> = (item: T) => { toString: () => string };
|
||||
|
||||
@Pipe({
|
||||
name: "search",
|
||||
})
|
||||
export class SearchPipe implements PipeTransform {
|
||||
transform(
|
||||
items: any[],
|
||||
transform<T>(
|
||||
items: T[],
|
||||
searchText: string,
|
||||
prop1?: string,
|
||||
prop2?: string,
|
||||
prop3?: string
|
||||
): any[] {
|
||||
prop1?: keyof T,
|
||||
prop2?: keyof T,
|
||||
prop3?: keyof T
|
||||
): T[];
|
||||
transform<T>(
|
||||
items: T[],
|
||||
searchText: string,
|
||||
prop1?: PropertyValueFunction<T>,
|
||||
prop2?: PropertyValueFunction<T>,
|
||||
prop3?: PropertyValueFunction<T>
|
||||
): T[];
|
||||
transform<T>(
|
||||
items: T[],
|
||||
searchText: string,
|
||||
prop1?: keyof T | PropertyValueFunction<T>,
|
||||
prop2?: keyof T | PropertyValueFunction<T>,
|
||||
prop3?: keyof T | PropertyValueFunction<T>
|
||||
): T[] {
|
||||
if (items == null || items.length === 0) {
|
||||
return [];
|
||||
}
|
||||
@@ -21,27 +37,30 @@ export class SearchPipe implements PipeTransform {
|
||||
|
||||
searchText = searchText.trim().toLowerCase();
|
||||
return items.filter((i) => {
|
||||
if (
|
||||
prop1 != null &&
|
||||
i[prop1] != null &&
|
||||
i[prop1].toString().toLowerCase().indexOf(searchText) > -1
|
||||
) {
|
||||
return true;
|
||||
if (prop1 != null) {
|
||||
const propValue = typeof prop1 === "function" ? prop1(i) : i[prop1];
|
||||
|
||||
if (propValue?.toString().toLowerCase().indexOf(searchText) > -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
prop2 != null &&
|
||||
i[prop2] != null &&
|
||||
i[prop2].toString().toLowerCase().indexOf(searchText) > -1
|
||||
) {
|
||||
return true;
|
||||
|
||||
if (prop2 != null) {
|
||||
const propValue = typeof prop2 === "function" ? prop2(i) : i[prop2];
|
||||
|
||||
if (propValue?.toString().toLowerCase().indexOf(searchText) > -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
prop3 != null &&
|
||||
i[prop3] != null &&
|
||||
i[prop3].toString().toLowerCase().indexOf(searchText) > -1
|
||||
) {
|
||||
return true;
|
||||
|
||||
if (prop3 != null) {
|
||||
const propValue = typeof prop3 === "function" ? prop3(i) : i[prop3];
|
||||
|
||||
if (propValue?.toString().toLowerCase().indexOf(searchText) > -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { CipherCreateRequest } from "../models/request/cipher-create.request";
|
||||
import { CipherPartialRequest } from "../models/request/cipher-partial.request";
|
||||
import { CipherShareRequest } from "../models/request/cipher-share.request";
|
||||
import { CipherRequest } from "../models/request/cipher.request";
|
||||
import { CollectionBulkDeleteRequest } from "../models/request/collection-bulk-delete.request";
|
||||
import { CollectionRequest } from "../models/request/collection.request";
|
||||
import { DeleteRecoverRequest } from "../models/request/delete-recover.request";
|
||||
import { DeviceVerificationRequest } from "../models/request/device-verification.request";
|
||||
@@ -316,13 +317,16 @@ export abstract class ApiService {
|
||||
) => Promise<AttachmentUploadDataResponse>;
|
||||
postAttachmentFile: (id: string, attachmentId: string, data: FormData) => Promise<any>;
|
||||
|
||||
getCollectionDetails: (
|
||||
organizationId: string,
|
||||
id: string
|
||||
) => Promise<CollectionAccessDetailsResponse>;
|
||||
getUserCollections: () => Promise<ListResponse<CollectionResponse>>;
|
||||
getCollections: (organizationId: string) => Promise<ListResponse<CollectionResponse>>;
|
||||
getCollectionUsers: (organizationId: string, id: string) => Promise<SelectionReadOnlyResponse[]>;
|
||||
getCollectionAccessDetails: (
|
||||
organizationId: string,
|
||||
id: string
|
||||
) => Promise<CollectionAccessDetailsResponse>;
|
||||
getManyCollectionsWithAccessDetails: (
|
||||
orgId: string
|
||||
) => Promise<ListResponse<CollectionAccessDetailsResponse>>;
|
||||
postCollection: (
|
||||
organizationId: string,
|
||||
request: CollectionRequest
|
||||
@@ -338,6 +342,7 @@ export abstract class ApiService {
|
||||
request: CollectionRequest
|
||||
) => Promise<CollectionResponse>;
|
||||
deleteCollection: (organizationId: string, id: string) => Promise<any>;
|
||||
deleteManyCollections: (request: CollectionBulkDeleteRequest) => Promise<any>;
|
||||
deleteCollectionUser: (
|
||||
organizationId: string,
|
||||
id: string,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Organization } from "../../models/domain/organization";
|
||||
import { I18nService } from "../i18n.service";
|
||||
|
||||
export function canAccessVaultTab(org: Organization): boolean {
|
||||
return org.isManager;
|
||||
return org.canViewAssignedCollections || org.canViewAllCollections || org.canManageGroups;
|
||||
}
|
||||
|
||||
export function canAccessSettingsTab(org: Organization): boolean {
|
||||
|
||||
84
libs/common/src/misc/serviceUtils.spec.ts
Normal file
84
libs/common/src/misc/serviceUtils.spec.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { TreeNode } from "../models/domain/tree-node";
|
||||
|
||||
import { ServiceUtils } from "./serviceUtils";
|
||||
|
||||
describe("serviceUtils", () => {
|
||||
type fakeObject = { id: string; name: string };
|
||||
let nodeTree: TreeNode<fakeObject>[];
|
||||
beforeEach(() => {
|
||||
nodeTree = [
|
||||
{
|
||||
parent: null,
|
||||
node: { id: "1", name: "1" },
|
||||
children: [
|
||||
{
|
||||
parent: { id: "1", name: "1" },
|
||||
node: { id: "1.1", name: "1.1" },
|
||||
children: [
|
||||
{
|
||||
parent: { id: "1.1", name: "1.1" },
|
||||
node: { id: "1.1.1", name: "1.1.1" },
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
parent: { id: "1", name: "1" },
|
||||
node: { id: "1.2", name: "1.2" },
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
parent: null,
|
||||
node: { id: "2", name: "2" },
|
||||
children: [
|
||||
{
|
||||
parent: { id: "2", name: "2" },
|
||||
node: { id: "2.1", name: "2.1" },
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
parent: null,
|
||||
node: { id: "3", name: "3" },
|
||||
children: [],
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
describe("nestedTraverse", () => {
|
||||
it("should traverse a tree and add a node at the correct position given a valid path", () => {
|
||||
const nodeToBeAdded: fakeObject = { id: "1.2.1", name: "1.2.1" };
|
||||
const path = ["1", "1.2", "1.2.1"];
|
||||
|
||||
ServiceUtils.nestedTraverse(nodeTree, 0, path, nodeToBeAdded, null, "/");
|
||||
expect(nodeTree[0].children[1].children[0].node).toEqual(nodeToBeAdded);
|
||||
});
|
||||
|
||||
it("should combine the path for missing nodes and use as the added node name given an invalid path", () => {
|
||||
const nodeToBeAdded: fakeObject = { id: "blank", name: "blank" };
|
||||
const path = ["3", "3.1", "3.1.1"];
|
||||
|
||||
ServiceUtils.nestedTraverse(nodeTree, 0, path, nodeToBeAdded, null, "/");
|
||||
expect(nodeTree[2].children[0].node.name).toEqual("3.1/3.1.1");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getTreeNodeObject", () => {
|
||||
it("should return a matching node given a single tree branch and a valid id", () => {
|
||||
const id = "1.1.1";
|
||||
const given = ServiceUtils.getTreeNodeObject(nodeTree[0], id);
|
||||
expect(given.node.id).toEqual(id);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getTreeNodeObjectFromList", () => {
|
||||
it("should return a matching node given a list of branches and a valid id", () => {
|
||||
const id = "1.1.1";
|
||||
const given = ServiceUtils.getTreeNodeObjectFromList(nodeTree, id);
|
||||
expect(given.node.id).toEqual(id);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8,7 +8,7 @@ export class ServiceUtils {
|
||||
* @param {string[]} parts - Array of strings that represent the path to the `obj` node
|
||||
* @param {ITreeNodeObject} obj - The node to be added to the tree
|
||||
* @param {ITreeNodeObject} parent - The parent node of the `obj` node
|
||||
* @param {string} delimiter - The delimiter used to split the path string
|
||||
* @param {string} delimiter - The delimiter used to split the path string, will be used to combine the path for missing nodes
|
||||
*/
|
||||
static nestedTraverse(
|
||||
nodeTree: TreeNode<ITreeNodeObject>[],
|
||||
@@ -22,18 +22,19 @@ export class ServiceUtils {
|
||||
return;
|
||||
}
|
||||
|
||||
const end = partIndex === parts.length - 1;
|
||||
const partName = parts[partIndex];
|
||||
const end: boolean = partIndex === parts.length - 1;
|
||||
const partName: string = parts[partIndex];
|
||||
|
||||
for (let i = 0; i < nodeTree.length; i++) {
|
||||
if (nodeTree[i].node.name !== parts[partIndex]) {
|
||||
if (nodeTree[i].node.name !== partName) {
|
||||
continue;
|
||||
}
|
||||
if (end && nodeTree[i].node.id !== obj.id) {
|
||||
// Another node with the same name.
|
||||
// Another node exists with the same name as the node being added
|
||||
nodeTree.push(new TreeNode(obj, parent, partName));
|
||||
return;
|
||||
}
|
||||
// Move down the tree to the next level
|
||||
ServiceUtils.nestedTraverse(
|
||||
nodeTree[i].children,
|
||||
partIndex + 1,
|
||||
@@ -45,12 +46,17 @@ export class ServiceUtils {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there's no node here with the same name...
|
||||
if (nodeTree.filter((n) => n.node.name === partName).length === 0) {
|
||||
// And we're at the end of the path given, add the node
|
||||
if (end) {
|
||||
nodeTree.push(new TreeNode(obj, parent, partName));
|
||||
return;
|
||||
}
|
||||
const newPartName = parts[partIndex] + delimiter + parts[partIndex + 1];
|
||||
// And we're not at the end of the path, combine the current name with the next name
|
||||
// 1, *1.2, 1.2.1 becomes
|
||||
// 1, *1.2/1.2.1
|
||||
const newPartName = partName + delimiter + parts[partIndex + 1];
|
||||
ServiceUtils.nestedTraverse(
|
||||
nodeTree,
|
||||
0,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
export class CollectionBulkDeleteRequest {
|
||||
ids: string[];
|
||||
organizationId: string;
|
||||
|
||||
constructor(ids: string[], organizationId?: string) {
|
||||
this.ids = ids == null ? [] : ids;
|
||||
this.organizationId = organizationId;
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import { CipherCreateRequest } from "../models/request/cipher-create.request";
|
||||
import { CipherPartialRequest } from "../models/request/cipher-partial.request";
|
||||
import { CipherShareRequest } from "../models/request/cipher-share.request";
|
||||
import { CipherRequest } from "../models/request/cipher.request";
|
||||
import { CollectionBulkDeleteRequest } from "../models/request/collection-bulk-delete.request";
|
||||
import { CollectionRequest } from "../models/request/collection.request";
|
||||
import { DeleteRecoverRequest } from "../models/request/delete-recover.request";
|
||||
import { DeviceVerificationRequest } from "../models/request/device-verification.request";
|
||||
@@ -812,7 +813,7 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
|
||||
// Collections APIs
|
||||
|
||||
async getCollectionDetails(
|
||||
async getCollectionAccessDetails(
|
||||
organizationId: string,
|
||||
id: string
|
||||
): Promise<CollectionAccessDetailsResponse> {
|
||||
@@ -842,6 +843,19 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
return new ListResponse(r, CollectionResponse);
|
||||
}
|
||||
|
||||
async getManyCollectionsWithAccessDetails(
|
||||
organizationId: string
|
||||
): Promise<ListResponse<CollectionAccessDetailsResponse>> {
|
||||
const r = await this.send(
|
||||
"GET",
|
||||
"/organizations/" + organizationId + "/collections/details",
|
||||
null,
|
||||
true,
|
||||
true
|
||||
);
|
||||
return new ListResponse(r, CollectionAccessDetailsResponse);
|
||||
}
|
||||
|
||||
async getCollectionUsers(
|
||||
organizationId: string,
|
||||
id: string
|
||||
@@ -909,6 +923,16 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
);
|
||||
}
|
||||
|
||||
deleteManyCollections(request: CollectionBulkDeleteRequest): Promise<any> {
|
||||
return this.send(
|
||||
"DELETE",
|
||||
"/organizations/" + request.organizationId + "/collections",
|
||||
request,
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
deleteCollectionUser(
|
||||
organizationId: string,
|
||||
id: string,
|
||||
|
||||
@@ -56,7 +56,7 @@ const commonStyles = [
|
||||
"before:-tw-inset-x-[0.1em]",
|
||||
"before:tw-rounded-md",
|
||||
"before:tw-transition",
|
||||
"before:tw-ring-2",
|
||||
"focus-visible:before:tw-ring-2",
|
||||
"focus-visible:before:tw-ring-text-contrast",
|
||||
"focus-visible:tw-z-10",
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user