Skip to content

Commit

Permalink
Labels (#8008)
Browse files Browse the repository at this point in the history
- Closes enso-org/cloud-v2#676
- Adds labels to the dashboard:
- Filtering assets by label
- Creating new labels
- Displaying labels in "Labels" column
- Adding a new label to an existing asset (multi-select)

# Important Notes
WIP: Use a color picker with pre-defined colors, instead of randomly generated colors
  • Loading branch information
somebody1234 authored Oct 17, 2023
1 parent e9fa127 commit c582571
Show file tree
Hide file tree
Showing 51 changed files with 1,284 additions and 150 deletions.
9 changes: 3 additions & 6 deletions app/ide-desktop/lib/assets/plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions app/ide-desktop/lib/assets/plus2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ export const SecretId = newtype.newtypeConstructor<SecretId>()
/** Unique identifier for an arbitrary asset. */
export type AssetId = IdType[keyof IdType]

/** Unique identifier for a file tag or project tag. */
/** The name of an asset label. */
export type LabelName = newtype.Newtype<string, 'LabelName'>
export const LabelName = newtype.newtypeConstructor<LabelName>()

/** Unique identifier for a label. */
export type TagId = newtype.Newtype<string, 'TagId'>
export const TagId = newtype.newtypeConstructor<TagId>()

Expand Down Expand Up @@ -240,29 +244,11 @@ export interface SecretInfo {
id: SecretId
}

/** The type of asset a specific tag can be applied to. */
export enum TagObjectType {
file = 'File',
project = 'Project',
}

/** A file tag or project tag. */
export interface Tag {
/* eslint-disable @typescript-eslint/naming-convention */
organization_id: UserOrOrganizationId
/** A label. */
export interface Label {
id: TagId
name: string
value: string
object_type: TagObjectType
object_id: string
/* eslint-enable @typescript-eslint/naming-convention */
}

/** Metadata uniquely identifying a file tag or project tag. */
export interface TagInfo {
id: TagId
name: string
value: string
value: LabelName
color: LChColor
}

/** Type of application that a {@link Version} applies to.
Expand Down Expand Up @@ -352,6 +338,47 @@ export enum FilterBy {
trashed = 'Trashed',
}

/** A color in the LCh colorspace. */
export interface LChColor {
readonly lightness: number
readonly chroma: number
readonly hue: number
readonly alpha?: number
}

/** A pre-selected list of colors to be used in color pickers. */
export const COLORS: readonly LChColor[] = [
/* eslint-disable @typescript-eslint/no-magic-numbers */
// Red
{ lightness: 50, chroma: 66, hue: 7 },
// Orange
{ lightness: 50, chroma: 66, hue: 34 },
// Yellow
{ lightness: 50, chroma: 66, hue: 80 },
// Turquoise
{ lightness: 50, chroma: 66, hue: 139 },
// Teal
{ lightness: 50, chroma: 66, hue: 172 },
// Blue
{ lightness: 50, chroma: 66, hue: 271 },
// Lavender
{ lightness: 50, chroma: 66, hue: 295 },
// Pink
{ lightness: 50, chroma: 66, hue: 332 },
// Light blue
{ lightness: 50, chroma: 22, hue: 252 },
// Dark blue
{ lightness: 22, chroma: 13, hue: 252 },
/* eslint-enable @typescript-eslint/no-magic-numbers */
]

/** Converts a {@link LChColor} to a CSS color string. */
export function lChColorToCssColor(color: LChColor): string {
return 'alpha' in color
? `lcha(${color.lightness}% ${color.chroma} ${color.hue} / ${color.alpha})`
: `lch(${color.lightness}% ${color.chroma} ${color.hue})`
}

// =================
// === AssetType ===
// =================
Expand Down Expand Up @@ -418,6 +445,7 @@ export interface BaseAsset {
* (and currently safe) to assume it is always a {@link DirectoryId}. */
parentId: DirectoryId
permissions: UserPermission[] | null
labels: LabelName[] | null
}

/** Metadata uniquely identifying a directory entry.
Expand Down Expand Up @@ -454,6 +482,7 @@ export function createSpecialLoadingAsset(directoryId: DirectoryId): SpecialLoad
parentId: directoryId,
permissions: [],
projectState: null,
labels: [],
}
}

Expand All @@ -471,6 +500,7 @@ export function createSpecialEmptyAsset(directoryId: DirectoryId): SpecialEmptyA
parentId: directoryId,
permissions: [],
projectState: null,
labels: [],
}
}

Expand Down Expand Up @@ -603,16 +633,15 @@ export interface CreateSecretRequestBody {

/** HTTP request body for the "create tag" endpoint. */
export interface CreateTagRequestBody {
name: string
value: string
objectType: TagObjectType
objectId: string
color: LChColor
}

/** URL query string parameters for the "list directory" endpoint. */
export interface ListDirectoryRequestParams {
parentId: string | null
filterBy: FilterBy | null
labels: LabelName[] | null
recentProjects: boolean
}

Expand All @@ -623,11 +652,6 @@ export interface UploadFileRequestParams {
parentDirectoryId: DirectoryId | null
}

/** URL query string parameters for the "list tags" endpoint. */
export interface ListTagsRequestParams {
tagType: TagObjectType
}

/** URL query string parameters for the "list versions" endpoint. */
export interface ListVersionsRequestParams {
versionType: VersionType
Expand Down Expand Up @@ -782,12 +806,18 @@ export abstract class Backend {
abstract getSecret(secretId: SecretId, title: string | null): Promise<Secret>
/** Return the secret environment variables accessible by the user. */
abstract listSecrets(): Promise<SecretInfo[]>
/** Create a file tag or project tag. */
abstract createTag(body: CreateTagRequestBody): Promise<TagInfo>
/** Return file tags or project tags accessible by the user. */
abstract listTags(params: ListTagsRequestParams): Promise<Tag[]>
/** Delete a file tag or project tag. */
abstract deleteTag(tagId: TagId): Promise<void>
/** Create a label used for categorizing assets. */
abstract createTag(body: CreateTagRequestBody): Promise<Label>
/** Return all labels accessible by the user. */
abstract listTags(): Promise<Label[]>
/** Set the full list of labels for a specific asset. */
abstract associateTag(
assetId: AssetId,
tagIds: LabelName[],
title: string | null
): Promise<void>
/** Delete a label. */
abstract deleteTag(tagId: TagId, value: LabelName): Promise<void>
/** Return a list of backend or IDE versions. */
abstract listVersions(params: ListVersionsRequestParams): Promise<Version[]>
}
Loading

0 comments on commit c582571

Please sign in to comment.