Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
3a53e8ae
Commit
3a53e8ae
authored
Jan 11, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
8ff41740
0f71b4bc
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
135 additions
and
89 deletions
+135
-89
app/assets/javascripts/notebook/cells/code.vue
app/assets/javascripts/notebook/cells/code.vue
+8
-7
app/assets/javascripts/notebook/cells/code/index.vue
app/assets/javascripts/notebook/cells/code/index.vue
+2
-1
app/assets/javascripts/notebook/cells/output/html.vue
app/assets/javascripts/notebook/cells/output/html.vue
+13
-2
app/assets/javascripts/notebook/cells/output/image.vue
app/assets/javascripts/notebook/cells/output/image.vue
+19
-1
app/assets/javascripts/notebook/cells/output/index.vue
app/assets/javascripts/notebook/cells/output/index.vue
+50
-54
app/assets/javascripts/notebook/cells/prompt.vue
app/assets/javascripts/notebook/cells/prompt.vue
+9
-1
app/assets/javascripts/notebook/index.vue
app/assets/javascripts/notebook/index.vue
+2
-2
app/models/pool_repository.rb
app/models/pool_repository.rb
+5
-1
app/models/project.rb
app/models/project.rb
+1
-1
changelogs/unreleased/notebook-multiple-outputs.yml
changelogs/unreleased/notebook-multiple-outputs.yml
+5
-0
spec/javascripts/notebook/cells/output/html_spec.js
spec/javascripts/notebook/cells/output/html_spec.js
+2
-0
spec/javascripts/notebook/cells/output/index_spec.js
spec/javascripts/notebook/cells/output/index_spec.js
+8
-19
spec/models/project_spec.rb
spec/models/project_spec.rb
+11
-0
No files found.
app/assets/javascripts/notebook/cells/code.vue
View file @
3a53e8ae
<
script
>
import
Code
Cell
from
'
./code/index.vue
'
;
import
Code
Output
from
'
./code/index.vue
'
;
import
OutputCell
from
'
./output/index.vue
'
;
export
default
{
name
:
'
CodeCell
'
,
components
:
{
'
code-cell
'
:
CodeCell
,
'
output-cell
'
:
OutputCell
,
CodeOutput
,
OutputCell
,
},
props
:
{
cell
:
{
...
...
@@ -29,8 +30,8 @@ export default {
hasOutput
()
{
return
this
.
cell
.
outputs
.
length
;
},
output
()
{
return
this
.
cell
.
outputs
[
0
]
;
output
s
()
{
return
this
.
cell
.
outputs
;
},
},
};
...
...
@@ -38,7 +39,7 @@ export default {
<
template
>
<div
class=
"cell"
>
<code-
cell
<code-
output
:raw-code=
"rawInputCode"
:count=
"cell.execution_count"
:code-css-class=
"codeCssClass"
...
...
@@ -47,7 +48,7 @@ export default {
<output-cell
v-if=
"hasOutput"
:count=
"cell.execution_count"
:output
=
"output
"
:output
s=
"outputs
"
:code-css-class=
"codeCssClass"
/>
</div>
...
...
app/assets/javascripts/notebook/cells/code/index.vue
View file @
3a53e8ae
...
...
@@ -3,8 +3,9 @@ import Prism from '../../lib/highlight';
import
Prompt
from
'
../prompt.vue
'
;
export
default
{
name
:
'
CodeOutput
'
,
components
:
{
prompt
:
Prompt
,
Prompt
,
},
props
:
{
count
:
{
...
...
app/assets/javascripts/notebook/cells/output/html.vue
View file @
3a53e8ae
...
...
@@ -4,13 +4,21 @@ import Prompt from '../prompt.vue';
export
default
{
components
:
{
prompt
:
Prompt
,
Prompt
,
},
props
:
{
count
:
{
type
:
Number
,
required
:
true
,
},
rawCode
:
{
type
:
String
,
required
:
true
,
},
index
:
{
type
:
Number
,
required
:
true
,
},
},
computed
:
{
sanitizedOutput
()
{
...
...
@@ -21,13 +29,16 @@ export default {
},
});
},
showOutput
()
{
return
this
.
index
===
0
;
},
},
};
</
script
>
<
template
>
<div
class=
"output"
>
<prompt
/>
<prompt
type=
"Out"
:count=
"count"
:show-output=
"showOutput"
/>
<div
v-html=
"sanitizedOutput"
></div>
</div>
</
template
>
app/assets/javascripts/notebook/cells/output/image.vue
View file @
3a53e8ae
...
...
@@ -6,6 +6,10 @@ export default {
prompt
:
Prompt
,
},
props
:
{
count
:
{
type
:
Number
,
required
:
true
,
},
outputType
:
{
type
:
String
,
required
:
true
,
...
...
@@ -14,10 +18,24 @@ export default {
type
:
String
,
required
:
true
,
},
index
:
{
type
:
Number
,
required
:
true
,
},
},
computed
:
{
imgSrc
()
{
return
`data:
${
this
.
outputType
}
;base64,
${
this
.
rawCode
}
`
;
},
showOutput
()
{
return
this
.
index
===
0
;
},
},
};
</
script
>
<
template
>
<div
class=
"output"
><prompt
/>
<img
:src=
"'data:' + outputType + ';base64,' + rawCode"
/></div>
<div
class=
"output"
>
<prompt
type=
"out"
:count=
"count"
:show-output=
"showOutput"
/>
<img
:src=
"imgSrc"
/>
</div>
</
template
>
app/assets/javascripts/notebook/cells/output/index.vue
View file @
3a53e8ae
<
script
>
import
Code
Cell
from
'
../code/index.vue
'
;
import
Html
from
'
./html.vue
'
;
import
Image
from
'
./image.vue
'
;
import
Code
Output
from
'
../code/index.vue
'
;
import
Html
Output
from
'
./html.vue
'
;
import
Image
Output
from
'
./image.vue
'
;
export
default
{
components
:
{
'
code-cell
'
:
CodeCell
,
'
html-output
'
:
Html
,
'
image-output
'
:
Image
,
},
props
:
{
codeCssClass
:
{
type
:
String
,
...
...
@@ -20,68 +15,69 @@ export default {
required
:
false
,
default
:
0
,
},
output
:
{
type
:
Object
,
output
s
:
{
type
:
Array
,
required
:
true
,
default
:
()
=>
({}),
},
},
computed
:
{
componentName
()
{
if
(
this
.
output
.
text
)
{
return
'
code-cell
'
;
}
else
if
(
this
.
output
.
data
[
'
image/png
'
])
{
return
'
image-output
'
;
}
else
if
(
this
.
output
.
data
[
'
text/html
'
])
{
return
'
html-output
'
;
}
else
if
(
this
.
output
.
data
[
'
image/svg+xml
'
])
{
return
'
html-output
'
;
}
data
()
{
return
{
outputType
:
''
,
};
},
methods
:
{
dataForType
(
output
,
type
)
{
let
data
=
output
.
data
[
type
];
return
'
code-cell
'
;
},
rawCode
()
{
if
(
this
.
output
.
text
)
{
return
this
.
output
.
text
.
join
(
''
);
if
(
typeof
data
===
'
object
'
)
{
data
=
data
.
join
(
''
);
}
return
this
.
dataForType
(
this
.
outputType
)
;
return
data
;
},
outputType
()
{
if
(
this
.
output
.
text
)
{
return
''
;
}
else
if
(
this
.
output
.
data
[
'
image/png
'
])
{
return
'
image/png
'
;
}
else
if
(
this
.
output
.
data
[
'
text/html
'
])
{
return
'
text/html
'
;
}
else
if
(
this
.
output
.
data
[
'
image/svg+xml
'
])
{
return
'
image/svg+xml
'
;
getComponent
(
output
)
{
if
(
output
.
text
)
{
return
CodeOutput
;
}
else
if
(
output
.
data
[
'
image/png
'
])
{
this
.
outputType
=
'
image/png
'
;
return
ImageOutput
;
}
else
if
(
output
.
data
[
'
text/html
'
])
{
this
.
outputType
=
'
text/html
'
;
return
HtmlOutput
;
}
else
if
(
output
.
data
[
'
image/svg+xml
'
])
{
this
.
outputType
=
'
image/svg+xml
'
;
return
HtmlOutput
;
}
return
'
text/plain
'
;
this
.
outputType
=
'
text/plain
'
;
return
CodeOutput
;
},
},
methods
:
{
dataForType
(
type
)
{
let
data
=
this
.
output
.
data
[
type
];
if
(
typeof
data
===
'
object
'
)
{
data
=
data
.
join
(
''
);
rawCode
(
output
)
{
if
(
output
.
text
)
{
return
output
.
text
.
join
(
''
);
}
return
data
;
return
this
.
dataForType
(
output
,
this
.
outputType
)
;
},
},
};
</
script
>
<
template
>
<component
:is=
"componentName"
:output-type=
"outputType"
:count=
"count"
:raw-code=
"rawCode"
:code-css-class=
"codeCssClass"
type=
"output"
/>
<div>
<component
:is=
"getComponent(output)"
v-for=
"(output, index) in outputs"
:key=
"index"
type=
"output"
:output-type=
"outputType"
:count=
"count"
:index=
"index"
:raw-code=
"rawCode(output)"
:code-css-class=
"codeCssClass"
/>
</div>
</
template
>
app/assets/javascripts/notebook/cells/prompt.vue
View file @
3a53e8ae
...
...
@@ -11,18 +11,26 @@ export default {
required
:
false
,
default
:
0
,
},
showOutput
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
},
computed
:
{
hasKeys
()
{
return
this
.
type
!==
''
&&
this
.
count
;
},
showTypeText
()
{
return
this
.
type
&&
this
.
count
&&
this
.
showOutput
;
},
},
};
</
script
>
<
template
>
<div
class=
"prompt"
>
<span
v-if=
"
hasKeys
"
>
{{
type
}}
[
{{
count
}}
]:
</span>
<span
v-if=
"
showTypeText
"
>
{{
type
}}
[
{{
count
}}
]:
</span>
</div>
</
template
>
...
...
app/assets/javascripts/notebook/index.vue
View file @
3a53e8ae
...
...
@@ -3,8 +3,8 @@ import { MarkdownCell, CodeCell } from './cells';
export
default
{
components
:
{
'
code-cell
'
:
CodeCell
,
'
markdown-cell
'
:
MarkdownCell
,
CodeCell
,
MarkdownCell
,
},
props
:
{
notebook
:
{
...
...
app/models/pool_repository.rb
View file @
3a53e8ae
...
...
@@ -85,7 +85,11 @@ class PoolRepository < ActiveRecord::Base
def
unlink_repository
(
repository
)
object_pool
.
unlink_repository
(
repository
.
raw
)
mark_obsolete
unless
member_projects
.
where
.
not
(
id:
repository
.
project
.
id
).
exists?
if
member_projects
.
where
.
not
(
id:
repository
.
project
.
id
).
exists?
true
else
mark_obsolete
end
end
def
object_pool
...
...
app/models/project.rb
View file @
3a53e8ae
...
...
@@ -2040,7 +2040,7 @@ class Project < ActiveRecord::Base
end
def
leave_pool_repository
pool_repository
&
.
unlink_repository
(
repository
)
pool_repository
&
.
unlink_repository
(
repository
)
&&
update_column
(
:pool_repository_id
,
nil
)
end
private
...
...
changelogs/unreleased/notebook-multiple-outputs.yml
0 → 100644
View file @
3a53e8ae
---
title
:
Support multiple outputs in jupyter notebooks
merge_request
:
author
:
type
:
changed
spec/javascripts/notebook/cells/output/html_spec.js
View file @
3a53e8ae
...
...
@@ -9,6 +9,8 @@ describe('html output cell', () => {
return
new
Component
({
propsData
:
{
rawCode
,
count
:
0
,
index
:
0
,
},
}).
$mount
();
}
...
...
spec/javascripts/notebook/cells/output/index_spec.js
View file @
3a53e8ae
...
...
@@ -10,7 +10,7 @@ describe('Output component', () => {
const
createComponent
=
output
=>
{
vm
=
new
Component
({
propsData
:
{
output
,
output
s
:
[].
concat
(
output
)
,
count
:
1
,
},
});
...
...
@@ -51,28 +51,21 @@ describe('Output component', () => {
it
(
'
renders as an image
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
img
'
)).
not
.
toBeNull
();
});
it
(
'
does not render the prompt
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.prompt span
'
)).
toBeNull
();
});
});
describe
(
'
html output
'
,
()
=>
{
beforeEach
(
done
=>
{
it
(
'
renders raw HTML
'
,
()
=>
{
createComponent
(
json
.
cells
[
4
].
outputs
[
0
]);
setTimeout
(()
=>
{
done
();
});
});
it
(
'
renders raw HTML
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
p
'
)).
not
.
toBeNull
();
expect
(
vm
.
$el
.
textContent
.
trim
()).
toBe
(
'
test
'
);
expect
(
vm
.
$el
.
querySelectorAll
(
'
p
'
).
length
).
toBe
(
1
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
test
'
);
});
it
(
'
does not render the prompt
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.prompt span
'
)).
toBeNull
();
it
(
'
renders multiple raw HTML outputs
'
,
()
=>
{
createComponent
([
json
.
cells
[
4
].
outputs
[
0
],
json
.
cells
[
4
].
outputs
[
0
]]);
expect
(
vm
.
$el
.
querySelectorAll
(
'
p
'
).
length
).
toBe
(
2
);
});
});
...
...
@@ -88,10 +81,6 @@ describe('Output component', () => {
it
(
'
renders as an svg
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
svg
'
)).
not
.
toBeNull
();
});
it
(
'
does not render the prompt
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.prompt span
'
)).
toBeNull
();
});
});
describe
(
'
default to plain text
'
,
()
=>
{
...
...
spec/models/project_spec.rb
View file @
3a53e8ae
...
...
@@ -4724,6 +4724,17 @@ describe Project do
end
end
describe
'#leave_pool_repository'
do
let
(
:pool
)
{
create
(
:pool_repository
)
}
let
(
:project
)
{
create
(
:project
,
:repository
,
pool_repository:
pool
)
}
it
'removes the membership'
do
project
.
leave_pool_repository
expect
(
pool
.
member_projects
.
reload
).
not_to
include
(
project
)
end
end
def
rugged_config
rugged_repo
(
project
.
repository
).
config
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment