Something went wrong on our end
-
Bastien Abadie authoredBastien Abadie authored
config.ts 13.29 KiB
import { WritingModeProperty, DirectionProperty } from 'csstype'
import { GitRefType, WorkerVersionState, WorkerActivityState, ModelVersionState } from './enums'
import { TextOrientation } from './types'
/*
* Build an object from all <meta> tags
* Check if `document` exists as it is not defined in unit tests
*/
const metas: { readonly [name: string]: string } = (typeof document !== 'undefined' && document)
? [...document.getElementsByTagName('meta')].reduce<Record<string, string>>((obj, meta) => { obj[meta.name] = meta.content; return obj }, {})
: {}
/*
* Get assets path from assets_url when available, and ensure there is an ending slash
* See https://webpack.js.org/guides/public-path/
*/
// eslint-disable-next-line camelcase
__webpack_public_path__ = (metas.assets_url || '').replace(/\/$/, '') + '/'
// Support fully specified URL with scheme, but also relative URLs to this page (like /api/v1)
let apiBaseUrl = metas.api_base_url || process.env.VUE_APP_API_BASE_URL || ''
if (typeof window !== 'undefined' && window) apiBaseUrl = new URL(apiBaseUrl, window.location.href).href
export const API_BASE_URL = apiBaseUrl
const csrfCookiesExceptions: { readonly [host: string]: string } = {
'ce.preprod.arkindex.teklia.com': 'ce.arkindex.preprod.csrf',
'ee.preprod.arkindex.teklia.com': 'ee.arkindex.preprod.csrf',
'dev.arkindex.teklia.com': 'arkindex.dev.csrf'
}
export const CSRF_COOKIE_NAME: string = process.env.VUE_APP_CSRF_COOKIE_NAME || (
/*
* Build a URI relative to the page's host; if the URI is absolute, the page host will be ignored
* Special case in unit tests: window is not defined
*/
(typeof window !== 'undefined' && window) && csrfCookiesExceptions[new URL(API_BASE_URL, window.location.origin).host]
// Fallback to default value
) || 'arkindex.csrf'
export const CSRF_COOKIE_HEADER = 'X-CSRFToken'
export const CSRF_ALL_ORIGINS = process.env.VUE_APP_CSRF_ALL_ORIGINS === 'true'
export const VERSION: string | undefined = process.env.VUE_APP_VERSION
export const ROUTER_MODE: string = process.env.VUE_APP_ROUTER_MODE || 'history'
export const UNIVERSAL_VIEWER: string | undefined = metas.universal_viewer_url
export const MIRADOR: string | undefined = metas.mirador_url
export const SENTRY_DSN: string | undefined = metas.sentry_dsn
export const SENTRY_ENVIRONMENT: string | undefined = metas.environment
export const DOORBELL_ID: string | undefined = metas.doorbell_id
export const DOORBELL_APPKEY: string | undefined = metas.doorbell_appkey
export const PROCESS_POLLING_DELAY = 4000
export const TASK_POLLING_DELAY = 4000
export const JOBS_POLLING_DELAY = 10000
// How long to wait after the last key press to update the suggested values
export const FILTER_BAR_SUGGESTION_DELAY = 1000
/*
* Django's UUID matching regex.
* Use this in the router for any path parameter of a UUID type via the path-to-regexp custom regex option:
* '/element/:id(\\d+)' would require an integer for `id`,
* and `/element/:id(${UUID})` will use this regex to get an UUID.
*/
export const UUID = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
export const UUID_REGEX = new RegExp(`^${UUID}$`)
// Limit text displayed length (characters)
export const TRUNCATE_LENGTHS = {
/**
* Limit options text size in `<select>` elements
* Also consider using `<span class="select is-truncated">` to truncate using CSS,
* but still display the full values when the user clicks on the `<select>`.
*/
select: 100,
/**
* Long truncate (e.g. Element names in navigation header or table display)
*/
long: 80,
/**
* Short truncate (e.g. Element types, compact components or thumbnails display)
*/
short: 30,
/**
* Character limit for notifications
*/
notification: 500,
/**
* Character limit for truncated UUIDs
*/
id: 8
} as const
// Maximum length of an element's name.
export const ELEMENT_NAME_MAX_LENGTH = 250
// Maximum number of suggestions in SearchableInput component
export const SEARCHABLE_SELECT_MAX_MATCHES = 15
// How long wait after the last key press to update the suggested values, in milliseconds
export const SEARCHABLE_SELECT_SUGGESTION_DELAY = 250
// Maximum amount of search terms the backend allows in search filters
export const SEARCH_FILTER_MAX_TERMS = 10
// Image definition related to available space
export const IMAGE_QUALITY = 1.5
// Interactive image zoom factor in percent
export const ZOOM_FACTORS = [100, 133, 166, 200, 250, 350, 400, 500]
// Image navigation transitions delay for the zoom and the automatic centering (ms)
export const IMAGE_TRANSITIONS = 300
// Margins allowed navigating through an interactive image in percentage of the image max(width, height)
export const NAVIGATION_MARGINS = 5
// Possible number of elements displayed in a page
export const NAVIGATION_PAGE_SIZES = [20, 50, 100, 500]
// Default page size, set when no ?page_size query parameter has been set
export const DEFAULT_PAGE_SIZE = 20
// Display a warning message once the ratio between the expected and actual image dimensions or area exceeds 80% or 120%
export const IMAGE_WARNING_RATIO = 0.8
// Interactive image drawing colors
export const DRAWN_POLYGON_COLOR = 'yellow'
export const DEFAULT_POLYGON_COLOR = '#28b62c'
export const HOVERED_TREE_ITEM_COLOR = '#ebffdb'
// Polygon minimal height and width (in pixels relatively to the image dimensions)
export const POLYGON_MIN_SIZE = 2
/*
* Maximum allowed consecutive distinct points in a polygon in the backend:
* AAABBBCCCBBBCCCCDDD has 6 distinct points even though B and C are repeated,
* but ABCDA has 4 distinct points because the last point is ignored when it is equal to the first.
*/
export const POLYGON_MAX_POINTS = 163
export const ELEMENT_LIST_MAX_AUTO_PAGES = 10
/**
* Margin applied around a node's label within the Graph component, in pixels.
*/
export const GRAPH_NODE_MARGIN = 10
export const PROCESS_STATES = {
unscheduled: 'Unscheduled',
pending: 'Pending',
running: 'Running',
completed: 'Completed',
failed: 'Task error',
error: 'System error',
stopping: 'Stopping',
stopped: 'Stopped'
} as const
/**
* States in which a process is finished; unless a task is forcefully restarted, a run in this state will not budge.
*/
export const PROCESS_FINAL_STATES: Array<keyof typeof PROCESS_STATES> = ['completed', 'failed', 'error', 'stopped']
export const PROCESS_MODES = {
files: 'Files',
repository: 'Git',
iiif: 'IIIF',
workers: 'Workers',
template: 'Template',
s3: 'S3',
dataset: 'Dataset'
} as const
interface ColorDefinition {
readonly cssClass: string
readonly background: string
readonly foreground?: string
}
/**
* Color coding for Ponos task states.
* `cssClass` defines the Bulma CSS class that should normally be used on HTML elements.
* `background` and `foreground` define the colors used within a SVG graph.
*/
export const PROCESS_STATE_COLORS: { readonly [state in keyof typeof PROCESS_STATES | 'default']: ColorDefinition } = {
unscheduled: {
cssClass: 'is-dark',
background: '#909090'
},
pending: {
cssClass: 'is-warning',
background: '#ffdd57'
},
running: {
cssClass: 'is-primary',
background: '#158cba'
},
completed: {
cssClass: 'is-success',
background: '#28b62c'
},
failed: {
cssClass: 'is-danger',
background: '#ff4136'
},
error: {
cssClass: 'is-danger',
background: '#ff4136'
},
stopping: {
cssClass: 'is-warning',
background: '#ffdd57'
},
stopped: {
cssClass: 'is-danger',
background: '#ff4136'
},
default: {
cssClass: '',
background: 'white',
foreground: 'black'
}
}
export const LOG_COLORS: { readonly [level: string]: string } = {
CRITICAL: '#ff291d',
ERROR: '#ff291d',
WARNING: '#ff9e26'
}
/**
* Color coding for worker types.
* `cssClass` defines the Bulma CSS class that should normally be used on HTML elements.
* `background` and `foreground` define the colors used within a SVG graph.
*/
export const WORKER_TYPE_COLORS: { readonly [workerType: string]: ColorDefinition } = {
classifier: {
cssClass: 'is-link',
background: '#5bb7db'
},
ner: {
cssClass: 'is-success',
background: '#28b62c'
},
recognizer: {
cssClass: 'is-warning',
background: '#ffdd57'
},
dla: {
cssClass: 'is-light',
background: '#363636',
foreground: 'white'
},
'word-segmenter': {
cssClass: 'is-danger',
background: '#ff291d'
},
default: {
cssClass: 'is-primary',
background: '#158cba',
foreground: 'black'
}
}
export const ACTIVITY_COLORS: { [key in WorkerActivityState]: string } = {
queued: 'is-light',
started: 'is-info',
processed: 'is-success',
error: 'is-danger'
} as const
export const MONTHS = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
] as const
export const MANUAL_WORKER_VERSION = '__manual__'
interface TextOrientationStyle {
writing: WritingModeProperty
display: string
direction?: DirectionProperty
}
/*
* Text orientation values to display and create non-left-to-right language transcriptions.
* "writing" is the value of the corresponding "writing-mode" CSS style property.
* For horizontal right to left text, a secondary "direction" style property also has to be specified.
* Vertical text orientations are currently not handled in the frontend.
*/
export const TEXT_ORIENTATIONS = {
'horizontal-lr': {
writing: 'horizontal-tb',
display: 'Left to Right'
},
'horizontal-rl': {
writing: 'horizontal-tb',
direction: 'rtl',
display: 'Right to Left'
}
} as Record<TextOrientation, TextOrientationStyle>
export const CLASSIFICATION_STATES = {
pending: 'pending',
validated: 'validated',
rejected: 'rejected'
} as const
export const METADATA_TYPES = {
text: {
icon: 'icon-feather',
display: 'Text'
},
markdown: {
icon: 'icon-doc',
display: 'Markdown'
},
date: {
icon: 'icon-date',
display: 'Date'
},
location: {
icon: 'icon-globe',
display: 'Location'
},
reference: {
icon: 'icon-bookmark',
display: 'Reference'
},
numeric: {
icon: 'icon-number',
display: 'Numeric'
},
url: {
icon: 'icon-link',
display: 'URL'
}
} as const
export const NOTIFICATION_TYPES = {
info: 'is-info',
warning: 'is-warning',
error: 'is-danger',
success: 'is-success'
} as const
export const EXPORT_STATES = {
created: 'Created',
running: 'Running',
done: 'Done',
failed: 'Failed'
} as const
export const DATASET_STATES = {
open: {
display_name: 'Open',
color: 'is-info'
},
building: {
display_name: 'Building',
color: 'is-warning'
},
complete: {
display_name: 'Complete',
color: 'is-success'
},
error: {
display_name: 'Error',
color: 'is-danger'
}
} as const
export const GIT_REF_COLORS: { [key in GitRefType]: string } = {
branch: 'is-secondary',
tag: 'is-success'
} as const
export const REVISION_STATE_COLORS: { [key in WorkerVersionState]: string } = {
created: 'is-info',
available: 'is-success',
processing: 'is-warning',
error: 'is-danger'
} as const
export const MODEL_VERSION_STATE_COLORS: { [key in ModelVersionState]: string } = {
created: 'is-info',
available: 'is-success',
error: 'is-danger'
} as const
// TODO: Type this with Partial<Corpus>, where `Corpus` is the type that defines a corpus in the corpora store once it switches to Pinia
export const DEFAULT_CORPUS_ATTRS = {
public: false,
description: '',
rights: ['read', 'write', 'admin'],
types: [{
slug: 'volume',
display_name: 'Volume',
folder: true
}, {
slug: 'page',
display_name: 'Page',
folder: false
}, {
slug: 'text_line',
display_name: 'Text line',
folder: false
}, {
slug: 'paragraph',
display_name: 'Paragraph',
folder: false
}],
created: '2000-01-01T01:00:00.000000Z',
authorized_users: 1
}
export interface Role {
readonly value: number
readonly display: string
readonly help: string
readonly tag: string
}
// Rights privileges level
export const ROLES: { readonly [name: string]: Role } = {
admin: {
value: 100,
display: 'Administrator',
help: 'Highest privilege level, allowing to perform any operation (including deletion).',
tag: 'is-danger is-light'
},
contributor: {
value: 50,
display: 'Contributor',
help: 'Intermediate privilege level, generally represented by a read and write access (e.g. to annotate elements).',
tag: 'is-warning is-light'
},
guest: {
value: 10,
display: 'Guest',
help: 'Lowest privilege level, allowing to retrieve information only (i.e. no edition).',
tag: 'is-info is-light'
}
}
export const BANNER_MESSAGE = metas.banner_message
export const BANNER_STYLE = metas.banner_style in NOTIFICATION_TYPES ? metas.banner_style : 'info'
/**
* MIME types of supported archives in file imports
*/
export const ARCHIVE_MIME_TYPES = [
// .zip, standard
'application/zip',
// .zip, from Windows only
'application/x-zip-compressed',
// .tar
'application/x-tar',
// .tar.gz, from libmagic only
'application/x-gtar',
// .tgz, from browsers only
'application/x-compressed-tar',
// .gz from anywhere, .tgz from libmagic only
'application/gzip',
// .bz2, from browsers only
'application/x-bzip',
// .bz2, from libmagic only
'application/x-bzip2',
// .lzma
'application/x-lzma',
// .xz
'application/x-xz',
// .zst
'application/zstd'
]