mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-09 00:22:38 +00:00
basic package aware autocomplete
This commit is contained in:
parent
cfca4b5d6c
commit
f113ba6342
13 changed files with 120 additions and 113 deletions
|
@ -1,28 +0,0 @@
|
|||
EditorRealTimeController = require "../Editor/EditorRealTimeController"
|
||||
LabelsHandler = require './LabelsHandler'
|
||||
logger = require 'logger-sharelatex'
|
||||
|
||||
|
||||
module.exports = LabelsController =
|
||||
|
||||
getAllLabels: (req, res, next) ->
|
||||
project_id = req.params.project_id
|
||||
logger.log {project_id}, "getting all labels for project"
|
||||
LabelsHandler.getAllMetaForProject project_id, (err, projectMeta) ->
|
||||
if err?
|
||||
logger.err {project_id, err}, "[LabelsController] error getting all labels from project"
|
||||
return next(err)
|
||||
res.json {projectId: project_id, projectMeta: projectMeta}
|
||||
|
||||
broadcastLabelsForDoc: (req, res, next) ->
|
||||
project_id = req.params.project_id
|
||||
doc_id = req.params.doc_id
|
||||
logger.log {project_id, doc_id}, "getting labels for doc"
|
||||
LabelsHandler.getMetaForDoc project_id, doc_id, (err, docMeta) ->
|
||||
if err?
|
||||
logger.err {project_id, doc_id, err}, "[LabelsController] error getting labels from doc"
|
||||
return next(err)
|
||||
EditorRealTimeController.emitToRoom project_id, 'broadcastDocMeta', {
|
||||
docId: doc_id, meta: docMeta
|
||||
}
|
||||
res.sendStatus(200)
|
|
@ -0,0 +1,29 @@
|
|||
EditorRealTimeController = require "../Editor/EditorRealTimeController"
|
||||
MetaHandler = require './MetaHandler'
|
||||
logger = require 'logger-sharelatex'
|
||||
|
||||
|
||||
module.exports = MetaController =
|
||||
|
||||
getMetadata: (req, res, next) ->
|
||||
project_id = req.params.project_id
|
||||
logger.log {project_id}, "getting all labels for project"
|
||||
MetaHandler.getAllMetaForProject project_id, (err, projectMeta) ->
|
||||
if err?
|
||||
logger.err {project_id, err}, "[MetaController] error getting all labels from project"
|
||||
return next err
|
||||
res.json {projectId: project_id, projectMeta: projectMeta}
|
||||
|
||||
broadcastMetadataForDoc: (req, res, next) ->
|
||||
project_id = req.params.project_id
|
||||
doc_id = req.params.doc_id
|
||||
logger.log {project_id, doc_id}, "getting labels for doc"
|
||||
MetaHandler.getMetaForDoc project_id, doc_id, (err, docMeta) ->
|
||||
if err?
|
||||
logger.err {project_id, doc_id, err}, "[MetaController] error getting labels from doc"
|
||||
return next err
|
||||
EditorRealTimeController.emitToRoom project_id, 'broadcastDocMeta', {
|
||||
docId: doc_id, meta: docMeta
|
||||
}
|
||||
res.sendStatus 200
|
||||
MetaController
|
|
@ -2,7 +2,7 @@ ProjectEntityHandler = require "../Project/ProjectEntityHandler"
|
|||
DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
|
||||
|
||||
|
||||
module.exports = LabelsHandler =
|
||||
module.exports = MetaHandler =
|
||||
|
||||
labelCaptureRegex: () ->
|
||||
/\\label\{([^\}\n\\]{0,80})\}/g
|
||||
|
@ -17,7 +17,7 @@ module.exports = LabelsHandler =
|
|||
ProjectEntityHandler.getAllDocs projectId, (err, docs) ->
|
||||
if err?
|
||||
return callback err
|
||||
projectMeta = LabelsHandler.extractMetaFromProjectDocs docs
|
||||
projectMeta = MetaHandler.extractMetaFromProjectDocs docs
|
||||
callback null, projectMeta
|
||||
|
||||
getMetaForDoc: (projectId, docId, callback=(err, docMeta)->) ->
|
||||
|
@ -27,13 +27,13 @@ module.exports = LabelsHandler =
|
|||
ProjectEntityHandler.getDoc projectId, docId, (err, lines) ->
|
||||
if err?
|
||||
return callback err
|
||||
docMeta = LabelsHandler.extractMetaFromDoc lines
|
||||
docMeta = MetaHandler.extractMetaFromDoc lines
|
||||
callback null, docMeta
|
||||
|
||||
extractMetaFromDoc: (lines) ->
|
||||
docMeta = {labels: [], packages: []}
|
||||
label_re = LabelsHandler.labelCaptureRegex()
|
||||
package_re = LabelsHandler.packageCaptureRegex()
|
||||
label_re = MetaHandler.labelCaptureRegex()
|
||||
package_re = MetaHandler.packageCaptureRegex()
|
||||
for line in lines
|
||||
while labelMatch = label_re.exec line
|
||||
if labelMatch[1]
|
||||
|
@ -41,11 +41,12 @@ module.exports = LabelsHandler =
|
|||
while packageMatch = package_re.exec line
|
||||
if packageMatch[2]
|
||||
for pkg in packageMatch[2].split ','
|
||||
docMeta.packages.push pkg.trim()
|
||||
if pkg.trim()
|
||||
docMeta.packages.push pkg.trim()
|
||||
return docMeta
|
||||
|
||||
extractMetaFromProjectDocs: (projectDocs) ->
|
||||
projectMeta = {}
|
||||
for _path, doc of projectDocs
|
||||
projectMeta[doc._id] = LabelsHandler.extractMetaFromDoc doc.lines
|
||||
projectMeta[doc._id] = MetaHandler.extractMetaFromDoc doc.lines
|
||||
return projectMeta
|
|
@ -43,8 +43,7 @@ SudoModeController = require('./Features/SudoMode/SudoModeController')
|
|||
SudoModeMiddlewear = require('./Features/SudoMode/SudoModeMiddlewear')
|
||||
AnalyticsRouter = require('./Features/Analytics/AnalyticsRouter')
|
||||
AnnouncementsController = require("./Features/Announcements/AnnouncementsController")
|
||||
LabelsController = require('./Features/Labels/LabelsController')
|
||||
# MetadataController = require('./Features/ProjectMetadata/MetadataController')
|
||||
MetaController = require('./Features/Metadata/MetaController')
|
||||
|
||||
logger = require("logger-sharelatex")
|
||||
_ = require("underscore")
|
||||
|
@ -202,8 +201,8 @@ module.exports = class Router
|
|||
webRouter.get '/Project/:Project_id/download/zip', AuthorizationMiddlewear.ensureUserCanReadProject, ProjectDownloadsController.downloadProject
|
||||
webRouter.get '/project/download/zip', AuthorizationMiddlewear.ensureUserCanReadMultipleProjects, ProjectDownloadsController.downloadMultipleProjects
|
||||
|
||||
webRouter.get '/project/:project_id/labels', AuthorizationMiddlewear.ensureUserCanReadProject, AuthenticationController.requireLogin(), LabelsController.getAllLabels
|
||||
webRouter.post '/project/:project_id/doc/:doc_id/labels', AuthorizationMiddlewear.ensureUserCanReadProject, AuthenticationController.requireLogin(), LabelsController.broadcastLabelsForDoc
|
||||
webRouter.get '/project/:project_id/metadata', AuthorizationMiddlewear.ensureUserCanReadProject, AuthenticationController.requireLogin(), MetaController.getMetadata
|
||||
webRouter.post '/project/:project_id/doc/:doc_id/metadata', AuthorizationMiddlewear.ensureUserCanReadProject, AuthenticationController.requireLogin(), MetaController.broadcastMetadataForDoc
|
||||
|
||||
webRouter.get '/tag', AuthenticationController.requireLogin(), TagsController.getAllTags
|
||||
webRouter.post '/tag', AuthenticationController.requireLogin(), TagsController.createTag
|
||||
|
|
|
@ -9,7 +9,7 @@ define [
|
|||
"ide/pdf/PdfManager"
|
||||
"ide/binary-files/BinaryFilesManager"
|
||||
"ide/references/ReferencesManager"
|
||||
"ide/labels/LabelsManager"
|
||||
"ide/metadata/MetadataManager"
|
||||
"ide/review-panel/ReviewPanelManager"
|
||||
"ide/SafariScrollPatcher"
|
||||
"ide/FeatureOnboardingController",
|
||||
|
@ -47,12 +47,12 @@ define [
|
|||
PdfManager
|
||||
BinaryFilesManager
|
||||
ReferencesManager
|
||||
LabelsManager
|
||||
MetadataManager
|
||||
ReviewPanelManager
|
||||
SafariScrollPatcher
|
||||
) ->
|
||||
|
||||
App.controller "IdeController", ($scope, $timeout, ide, localStorage, sixpack, event_tracking, labels) ->
|
||||
App.controller "IdeController", ($scope, $timeout, ide, localStorage, sixpack, event_tracking, metadata) ->
|
||||
# Don't freak out if we're already in an apply callback
|
||||
$scope.$originalApply = $scope.$apply
|
||||
$scope.$apply = (fn = () ->) ->
|
||||
|
@ -72,10 +72,10 @@ define [
|
|||
view: "editor"
|
||||
chatOpen: false
|
||||
pdfLayout: 'sideBySide'
|
||||
pdfHidden: false,
|
||||
pdfWidth: 0,
|
||||
reviewPanelOpen: localStorage("ui.reviewPanelOpen.#{window.project_id}"),
|
||||
miniReviewPanelVisible: false,
|
||||
pdfHidden: false
|
||||
pdfWidth: 0
|
||||
reviewPanelOpen: localStorage("ui.reviewPanelOpen.#{window.project_id}")
|
||||
miniReviewPanelVisible: false
|
||||
}
|
||||
$scope.onboarding = {
|
||||
autoCompile: if window.user.betaProgram and window.showAutoCompileOnboarding then 'unseen' else 'dismissed'
|
||||
|
@ -140,7 +140,7 @@ define [
|
|||
ide.pdfManager = new PdfManager(ide, $scope)
|
||||
ide.permissionsManager = new PermissionsManager(ide, $scope)
|
||||
ide.binaryFilesManager = new BinaryFilesManager(ide, $scope)
|
||||
ide.labelsManager = new LabelsManager(ide, $scope, labels)
|
||||
ide.metadataManager = new MetadataManager(ide, $scope, metadata)
|
||||
|
||||
inited = false
|
||||
$scope.$on "project:joined", () ->
|
||||
|
@ -155,7 +155,7 @@ define [
|
|||
$timeout(
|
||||
() ->
|
||||
if $scope.permissions.write
|
||||
ide.labelsManager.loadProjectLabelsFromServer()
|
||||
ide.metadataManager.loadProjectMetaFromServer()
|
||||
_labelsInitialLoadDone = true
|
||||
, 200
|
||||
)
|
||||
|
|
|
@ -9,11 +9,11 @@ define [
|
|||
"ide/editor/directives/aceEditor/highlights/HighlightsManager"
|
||||
"ide/editor/directives/aceEditor/cursor-position/CursorPositionManager"
|
||||
"ide/editor/directives/aceEditor/track-changes/TrackChangesManager"
|
||||
"ide/editor/directives/aceEditor/labels/LabelsManager"
|
||||
"ide/labels/services/labels"
|
||||
"ide/editor/directives/aceEditor/metadata/MetadataManager"
|
||||
"ide/metadata/services/metadata"
|
||||
"ide/graphics/services/graphics"
|
||||
"ide/preamble/services/preamble"
|
||||
], (App, Ace, SearchBox, ModeList, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager, TrackChangesManager, LabelsManager) ->
|
||||
], (App, Ace, SearchBox, ModeList, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager, TrackChangesManager, MetadataManager) ->
|
||||
EditSession = ace.require('ace/edit_session').EditSession
|
||||
ModeList = ace.require('ace/ext/modelist')
|
||||
|
||||
|
@ -35,9 +35,8 @@ define [
|
|||
url = ace.config._moduleUrl(args...) + "?fingerprint=#{window.aceFingerprint}"
|
||||
return url
|
||||
|
||||
# console.log 'making it to right before aceEditor'
|
||||
|
||||
App.directive "aceEditor", ($timeout, $compile, $rootScope, event_tracking, localStorage, $cacheFactory, labels, graphics, preamble) ->
|
||||
App.directive "aceEditor", ($timeout, $compile, $rootScope, event_tracking, localStorage, $cacheFactory, metadata, graphics, preamble) ->
|
||||
monkeyPatchSearch($rootScope, $compile)
|
||||
|
||||
return {
|
||||
|
@ -104,8 +103,8 @@ define [
|
|||
highlightsManager = new HighlightsManager(scope, editor, element)
|
||||
cursorPositionManager = new CursorPositionManager(scope, editor, element, localStorage)
|
||||
trackChangesManager = new TrackChangesManager(scope, editor, element)
|
||||
labelsManager = new LabelsManager(scope, editor, element, labels)
|
||||
autoCompleteManager = new AutoCompleteManager(scope, editor, element, labelsManager, graphics, preamble)
|
||||
metadataManager = new MetadataManager(scope, editor, element, metadata)
|
||||
autoCompleteManager = new AutoCompleteManager(scope, editor, element, metadataManager, graphics, preamble)
|
||||
|
||||
|
||||
# Prevert Ctrl|Cmd-S from triggering save dialog
|
||||
|
|
|
@ -9,8 +9,7 @@ define [
|
|||
aceSnippetManager = ace.require('ace/snippets').snippetManager
|
||||
|
||||
class AutoCompleteManager
|
||||
constructor: (@$scope, @editor, @element, @labelsManager, @graphics, @preamble) ->
|
||||
@suggestionManager = new CommandManager(@labelsManager)
|
||||
constructor: (@$scope, @editor, @element, @metadataManager, @graphics, @preamble) ->
|
||||
|
||||
@monkeyPatchAutocomplete()
|
||||
|
||||
|
@ -34,7 +33,7 @@ define [
|
|||
enableLiveAutocompletion: false
|
||||
})
|
||||
|
||||
# metadataManager = @metadataManager
|
||||
commandCompleter = new CommandManager(@metadataManager)
|
||||
|
||||
SnippetCompleter = new EnvironmentManager()
|
||||
|
||||
|
@ -65,7 +64,7 @@ define [
|
|||
}
|
||||
callback null, result
|
||||
|
||||
labelsManager = @labelsManager
|
||||
metadataManager = @metadataManager
|
||||
LabelsCompleter =
|
||||
getCompletions: (editor, session, pos, prefix, callback) ->
|
||||
context = Helpers.getContext(editor, pos)
|
||||
|
@ -83,7 +82,7 @@ define [
|
|||
meta: "cross-reference",
|
||||
score: 60
|
||||
}
|
||||
for label in labelsManager.getAllLabels()
|
||||
for label in metadataManager.getAllLabels()
|
||||
result.push {
|
||||
caption: "\\#{commandName}{#{label}#{if needsClosingBrace then '}' else ''}",
|
||||
value: "\\#{commandName}{#{label}#{if needsClosingBrace then '}' else ''}",
|
||||
|
@ -129,10 +128,10 @@ define [
|
|||
callback null, result
|
||||
|
||||
@editor.completers = [
|
||||
@suggestionManager,
|
||||
SnippetCompleter,
|
||||
ReferencesCompleter,
|
||||
LabelsCompleter,
|
||||
commandCompleter
|
||||
SnippetCompleter
|
||||
ReferencesCompleter
|
||||
LabelsCompleter
|
||||
GraphicsCompleter
|
||||
]
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
define [], () ->
|
||||
define [
|
||||
"./package_definitions"
|
||||
], (packageCommandMappings) ->
|
||||
noArgumentCommands = [
|
||||
'item', 'hline', 'lipsum', 'centering', 'noindent', 'textwidth', 'draw',
|
||||
'maketitle', 'newpage', 'verb', 'bibliography', 'hfill', 'par',
|
||||
|
@ -77,10 +79,10 @@ define [], () ->
|
|||
special
|
||||
)
|
||||
|
||||
packageCommandMappings = {
|
||||
amsmath: ['holyshititworks', 'mathematics']
|
||||
natbib: ['somebibliographystuff']
|
||||
}
|
||||
# packageCommandMappings = {
|
||||
# amsmath: ['holyshititworks', 'mathematics']
|
||||
# natbib: ['somebibliographystuff']
|
||||
# }
|
||||
|
||||
class Parser
|
||||
constructor: (@doc, @prefix) ->
|
||||
|
@ -171,10 +173,10 @@ define [], () ->
|
|||
return false
|
||||
|
||||
class CommandManager
|
||||
constructor: (@labelsManager) ->
|
||||
constructor: (@metadataManager) ->
|
||||
|
||||
getCompletions: (editor, session, pos, prefix, callback) ->
|
||||
packages = @labelsManager.getAllPackages()
|
||||
packages = @metadataManager.getAllPackages()
|
||||
packageCommands = []
|
||||
for pkg in packages
|
||||
if packageCommandMappings[pkg]?
|
||||
|
@ -182,7 +184,8 @@ define [], () ->
|
|||
packageCommands.push {
|
||||
caption: "\\#{cmd}"
|
||||
snippet: "\\#{cmd}"
|
||||
meta: "cmd"
|
||||
meta: "#{pkg}-cmd"
|
||||
score: 60
|
||||
}
|
||||
|
||||
doc = session.getValue()
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -9,8 +9,8 @@ define [
|
|||
else
|
||||
return null
|
||||
|
||||
class LabelsManager
|
||||
constructor: (@$scope, @editor, @element, @Labels) ->
|
||||
class MetadataManager
|
||||
constructor: (@$scope, @editor, @element, @Metadata) ->
|
||||
@debouncer = {} # DocId => Timeout
|
||||
|
||||
onChange = (change) =>
|
||||
|
@ -21,8 +21,12 @@ define [
|
|||
cursorPosition = @editor.getCursorPosition()
|
||||
end = change.end
|
||||
range = new Range(end.row, 0, end.row, end.column)
|
||||
lineUpToCursor = @editor.getSession().getTextRange(range)
|
||||
commandFragment = getLastCommandFragment(lineUpToCursor)
|
||||
lineUpToCursor = @editor.getSession().getTextRange range
|
||||
if lineUpToCursor.trim() == '%' or lineUpToCursor.startsWith '\\'
|
||||
# fix in case change is just (un)comment out a package
|
||||
range = new Range end.row, 0, end.row, end.column + 80
|
||||
lineUpToCursor = @editor.getSession().getTextRange range
|
||||
commandFragment = getLastCommandFragment lineUpToCursor
|
||||
|
||||
linesContainPackage = _.any(
|
||||
change.lines,
|
||||
|
@ -39,20 +43,20 @@ define [
|
|||
lastCommandFragmentIsMeta = lastCommandFragmentIsPackage or lastCommandFragmentIsLabel
|
||||
|
||||
if linesContainMeta or lastCommandFragmentIsMeta
|
||||
@scheduleLoadCurrentDocLabelsFromServer()
|
||||
@scheduleLoadCurrentDocMetaFromServer()
|
||||
|
||||
@editor.on "changeSession", (e) =>
|
||||
e.oldSession.off "change", onChange
|
||||
e.session.on "change", onChange
|
||||
|
||||
loadCurrentDocLabelsFromServer: () ->
|
||||
currentDocId = @$scope.docId
|
||||
@Labels.loadDocLabelsFromServer currentDocId
|
||||
# loadCurrentDocLabelsFromServer: () ->
|
||||
# currentDocId = @$scope.docId
|
||||
# @Metadata.loadDocMetaFromServer currentDocId
|
||||
|
||||
loadDocLabelsFromServer: (docId) ->
|
||||
@Labels.loadDocLabelsFromServer docId
|
||||
loadDocMetaFromServer: (docId) ->
|
||||
@Metadata.loadDocMetaFromServer docId
|
||||
|
||||
scheduleLoadCurrentDocLabelsFromServer: () ->
|
||||
scheduleLoadCurrentDocMetaFromServer: () ->
|
||||
# De-bounce loading labels with a timeout
|
||||
currentDocId = @$scope.docId
|
||||
existingTimeout = @debouncer[currentDocId]
|
||||
|
@ -61,14 +65,14 @@ define [
|
|||
delete @debouncer[currentDocId]
|
||||
@debouncer[currentDocId] = setTimeout(
|
||||
() =>
|
||||
@loadDocLabelsFromServer currentDocId
|
||||
@loadDocMetaFromServer currentDocId
|
||||
delete @debouncer[currentDocId]
|
||||
, 1000
|
||||
, this
|
||||
)
|
||||
|
||||
getAllLabels: () ->
|
||||
@Labels.getAllLabels()
|
||||
@Metadata.getAllLabels()
|
||||
|
||||
getAllPackages: () ->
|
||||
@Labels.getAllPackages()
|
||||
@Metadata.getAllPackages()
|
|
@ -1,13 +0,0 @@
|
|||
define [], () ->
|
||||
|
||||
class LabelsManager
|
||||
|
||||
constructor: (@ide, @$scope, @labels) ->
|
||||
|
||||
@ide.socket.on 'broadcastDocMeta', (data) =>
|
||||
@labels.onBroadcastDocLabels data
|
||||
@$scope.$on 'entity:deleted', @labels.onEntityDeleted
|
||||
@$scope.$on 'file:upload:complete', @labels.fileUploadComplete
|
||||
|
||||
loadProjectLabelsFromServer: () ->
|
||||
@labels.loadProjectLabelsFromServer()
|
|
@ -0,0 +1,13 @@
|
|||
define [], () ->
|
||||
|
||||
class MetadataManager
|
||||
|
||||
constructor: (@ide, @$scope, @metadata) ->
|
||||
|
||||
@ide.socket.on 'broadcastDocMeta', (data) =>
|
||||
@metadata.onBroadcastDocMeta data
|
||||
@$scope.$on 'entity:deleted', @metadata.onEntityDeleted
|
||||
@$scope.$on 'file:upload:complete', @metadata.fileUploadComplete
|
||||
|
||||
loadProjectMetaFromServer: () ->
|
||||
@metadata.loadProjectMetaFromServer()
|
|
@ -2,46 +2,46 @@ define [
|
|||
"base"
|
||||
], (App) ->
|
||||
|
||||
App.factory 'labels', ($http, ide) ->
|
||||
App.factory 'metadata', ($http, ide) ->
|
||||
|
||||
state = {documents: {}}
|
||||
|
||||
labels = {
|
||||
metadata = {
|
||||
state: state
|
||||
}
|
||||
|
||||
labels.onBroadcastDocLabels = (data) ->
|
||||
metadata.onBroadcastDocMeta = (data) ->
|
||||
if data.docId? and data.meta?
|
||||
state.documents[data.docId] = data.meta
|
||||
|
||||
labels.onEntityDeleted = (e, entity) ->
|
||||
metadata.onEntityDeleted = (e, entity) ->
|
||||
if entity.type == 'doc'
|
||||
delete state.documents[entity.id]
|
||||
|
||||
labels.onFileUploadComplete = (e, upload) ->
|
||||
metadata.onFileUploadComplete = (e, upload) ->
|
||||
if upload.entity_type == 'doc'
|
||||
labels.loadDocLabelsFromServer upload.entity_id
|
||||
metadata.loadDocMetaFromServer upload.entity_id
|
||||
|
||||
labels.getAllLabels = () ->
|
||||
metadata.getAllLabels = () ->
|
||||
_.flatten(meta.labels for docId, meta of state.documents)
|
||||
|
||||
labels.getAllPackages = () ->
|
||||
metadata.getAllPackages = () ->
|
||||
_.flatten(meta.packages for docId, meta of state.documents)
|
||||
|
||||
labels.loadProjectLabelsFromServer = () ->
|
||||
metadata.loadProjectMetaFromServer = () ->
|
||||
$http
|
||||
.get("/project/#{window.project_id}/labels")
|
||||
.get("/project/#{window.project_id}/metadata")
|
||||
.then (response) ->
|
||||
{ data } = response
|
||||
if data.projectMeta
|
||||
for docId, docMeta of data.projectMeta
|
||||
state.documents[docId] = docMeta.labels
|
||||
state.documents[docId] = docMeta
|
||||
|
||||
labels.loadDocLabelsFromServer = (docId) ->
|
||||
metadata.loadDocMetaFromServer = (docId) ->
|
||||
$http
|
||||
.post(
|
||||
"/project/#{window.project_id}/doc/#{docId}/labels",
|
||||
"/project/#{window.project_id}/doc/#{docId}/metadata",
|
||||
{_csrf: window.csrfToken}
|
||||
)
|
||||
|
||||
return labels
|
||||
return metadata
|
Loading…
Add table
Reference in a new issue