Show history in all wiki pages

stable
Xavier Julián 2016-06-07 10:17:47 +02:00 committed by David Barragán Merino
parent e488fac8d1
commit 8de4db9e37
28 changed files with 578 additions and 88 deletions

View File

@ -18,6 +18,7 @@
- Wiki: - Wiki:
- Drag & Drop ordering for wiki links. - Drag & Drop ordering for wiki links.
- Add a list of all wiki pages - Add a list of all wiki pages
- Add Wiki history
### Misc ### Misc
- Lots of small and not so small bugfixes. - Lots of small and not so small bugfixes.

View File

@ -779,6 +779,7 @@ modules = [
"taigaExternalApps", "taigaExternalApps",
"taigaDiscover", "taigaDiscover",
"taigaHistory", "taigaHistory",
"taigaWikiHistory",
# template cache # template cache
"templates", "templates",

View File

@ -131,7 +131,7 @@ urls = {
"history/us": "/history/userstory" "history/us": "/history/userstory"
"history/issue": "/history/issue" "history/issue": "/history/issue"
"history/task": "/history/task" "history/task": "/history/task"
"history/wiki": "/history/wiki" "history/wiki": "/history/wiki/%s"
# Attachments # Attachments
"attachments/us": "/userstories/attachments" "attachments/us": "/userstories/attachments"

View File

@ -218,7 +218,8 @@ module.directive("tgWikiSummary", ["$log", "$tgTemplate", "$compile", "$translat
## Editable Wiki Content Directive ## Editable Wiki Content Directive
############################################################################# #############################################################################
EditableWikiContentDirective = ($window, $document, $repo, $confirm, $loading, $analytics, $qqueue, $translate) -> EditableWikiContentDirective = ($window, $document, $repo, $confirm, $loading, $analytics, $qqueue, $translate,
$wikiHistoryService) ->
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
isEditable = -> isEditable = ->
return $scope.project.my_permissions.indexOf("modify_wiki_page") != -1 return $scope.project.my_permissions.indexOf("modify_wiki_page") != -1
@ -260,6 +261,7 @@ EditableWikiContentDirective = ($window, $document, $repo, $confirm, $loading, $
$model.$setViewValue wikiPage.clone() $model.$setViewValue wikiPage.clone()
$wikiHistoryService.loadHistoryEntries()
$confirm.notify("success") $confirm.notify("success")
switchToReadMode() switchToReadMode()
@ -336,4 +338,5 @@ EditableWikiContentDirective = ($window, $document, $repo, $confirm, $loading, $
} }
module.directive("tgEditableWikiContent", ["$window", "$document", "$tgRepo", "$tgConfirm", "$tgLoading", module.directive("tgEditableWikiContent", ["$window", "$document", "$tgRepo", "$tgConfirm", "$tgLoading",
"$tgAnalytics", "$tgQqueue", "$translate", EditableWikiContentDirective]) "$tgAnalytics", "$tgQqueue", "$translate", "tgWikiHistoryService",
EditableWikiContentDirective])

View File

@ -1,7 +1,7 @@
nav.history-tabs nav.history-tabs
a.history-tab.e2e-comments-tab( a.history-tab.e2e-comments-tab(
href="" href=""
title="Comments" title="{{COMMENTS.COMMENT}}"
ng-click="onActiveComments()" ng-click="onActiveComments()"
ng-class="{active: activeTab}" ng-class="{active: activeTab}"
translate="COMMENTS.COMMENTS_COUNT" translate="COMMENTS.COMMENTS_COUNT"

View File

@ -1,25 +1,4 @@
.history-tabs { .history-tabs {
background: $whitish;
display: flex;
flex-direction: row;
a {
color: $grayer;
display: inline-block;
padding: .75rem 1rem;
&:hover {
color: $primary;
}
}
.history-tab {
@include font-type(bold);
border-bottom: 3px solid transparent;
color: $gray-light;
transition: all .1s linear;
&.active {
border-bottom: 3px solid $grayer;
color: $grayer;
}
}
.order-comments { .order-comments {
@include font-type(light); @include font-type(light);
margin-left: auto; margin-left: auto;

View File

@ -17,9 +17,12 @@
p { p {
display: inline-block; display: inline-block;
} }
del { ins {
background: lighten(rgba($primary-light, .3), 20%); background: lighten(rgba($primary-light, .3), 20%);
text-decoration: underline; text-decoration: underline;
} }
del {
background: rgba($red-light, .3);
}
} }
} }

View File

@ -1,10 +1,8 @@
.activities {
.activity { .activity {
align-items: flex-start; align-items: flex-start;
border-bottom: 1px solid $whitish; border-bottom: 1px solid $whitish;
display: flex; display: flex;
padding: 2rem 0; padding: 2rem 0;
}
.activity-avatar { .activity-avatar {
flex-basis: 50px; flex-basis: 50px;
flex-shrink: 0; flex-shrink: 0;
@ -20,30 +18,4 @@
.activity-date { .activity-date {
color: $gray-light; color: $gray-light;
} }
.comment-options {
align-items: center;
align-self: stretch;
display: flex;
flex-basis: 50px;
flex-shrink: 0;
margin-left: 1.5rem;
.comment-option {
cursor: pointer;
opacity: 0;
transition: opacity .2s;
}
.icon-edit {
fill: $gray-light;
margin-right: .5rem;
&:hover {
fill: $gray;
}
}
.icon-trash {
fill: $red-light;
&:hover {
fill: $red;
}
}
}
} }

View File

@ -26,7 +26,8 @@ services = [
"tgIssuesResource", "tgIssuesResource",
"tgExternalAppsResource", "tgExternalAppsResource",
"tgAttachmentsResource", "tgAttachmentsResource",
"tgStatsResource" "tgStatsResource",
"tgWikiHistory"
] ]
Resources = ($injector) -> Resources = ($injector) ->

View File

@ -0,0 +1,42 @@
###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: wiki-resource.service.coffee
###
Resource = (urlsService, http) ->
service = {}
service.getWikiHistory = (wikiId) ->
url = urlsService.resolve("history/wiki", wikiId)
httpOptions = {
headers: {
"x-disable-pagination": "1"
}
}
return http.get(url, null, httpOptions)
.then (result) ->
return Immutable.fromJS(result.data)
return () ->
return {"wikiHistory": service}
Resource.$inject = ["$tgUrls", "$tgHttp"]
module = angular.module("taigaResources2")
module.factory("tgWikiHistory", Resource)

View File

@ -0,0 +1,42 @@
//- New attachment added
.diff-attachments-new(
ng-if="diff.new.length"
ng-repeat="newAttachment in diff.new"
)
span.key(translate="ACTIVITY.NEW_ATTACHMENT")
span.diff {{newAttachment.filename}}
//- Attachment updated
.diff-attachments-update(
ng-if="diff.changed.length"
ng-repeat="editAttachment in diff.changed"
)
span.key(
translate="ACTIVITY.UPDATED_ATTACHMENT"
translate-values="{filename: editAttachment.filename}"
)
span.diff(ng-if="editAttachment.changes.is_deprecated")
span(
ng-if="editAttachment.changes.is_deprecated[1] == false"
translate="ACTIVITY.BECAME_UNDEPRECATED"
)
span(
ng-if="editAttachment.changes.is_deprecated[1] == true"
translate="ACTIVITY.BECAME_DEPRECATED"
)
span.diff(ng-if="editAttachment.changes.description")
span(ng-if='editAttachment.changes.description[0].length') {{editAttachment.changes.description[0]}}
span(ng-if='!editAttachment.changes.description[0].length') ...
tg-svg(
svg-icon="icon-arrow-right"
)
span {{editAttachment.changes.description[1]}}
//- Attachment deleted
.diff-attachments-deleted(
ng-if="diff.deleted.length"
ng-repeat="deletedAttachment in diff.deleted"
)
span.key(translate="ACTIVITY.DELETED_ATTACHMENT")
span.diff {{deletedAttachment.filename}}

View File

@ -0,0 +1,31 @@
###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: wiki-history.directive.coffee
###
module = angular.module('taigaWikiHistory')
WikiHistoryDiffDirective = () ->
return {
templateUrl:"wiki/history/wiki-history-diff.html",
scope: {
key: "<",
diff: "<"
}
}
module.directive("tgWikiHistoryDiff", WikiHistoryDiffDirective)

View File

@ -0,0 +1,16 @@
.diff-status-wrapper(
ng-if="key === 'attachments'"
)
include history-templates/history-attachments
.diff-status-wrapper(
ng-if="key === 'content_diff'"
)
p.diff(
ng-if="diff[0]"
ng-bind-html="diff[0]"
)
p.diff(
ng-if="diff[1]"
ng-bind-html="diff[1]"
)

View File

@ -0,0 +1,34 @@
###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: wiki-history.directive.coffee
###
module = angular.module('taigaWikiHistory')
WikiHistoryEntryDirective = () ->
link = (scope, el, attr) ->
scope.singleHistoryEntry = scope.historyEntry.toJS()
return {
link: link,
templateUrl:"wiki/history/wiki-history-entry.html",
scope: {
historyEntry: "<"
}
}
module.directive("tgWikiHistoryEntry", WikiHistoryEntryDirective)

View File

@ -0,0 +1,16 @@
.activity
img.activity-avatar(
ng-src="{{singleHistoryEntry.user.photo}}"
ng-alt="{{singleHistoryEntry.user.name}}"
)
.activity-main
.activity-data
span.activity-creator {{singleHistoryEntry.user.name}}
span.activity-date {{singleHistoryEntry.created_at | momentFormat:'DD MMM YYYY HH:mm'}}
.activity-diff(
ng-repeat="(key, diff) in singleHistoryEntry.values_diff"
tg-wiki-history-diff
key='key'
diff='diff'
)

View File

@ -0,0 +1,38 @@
###
# Copyright (C) 2014-2015 Taiga Agile LLC <taiga@taiga.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: wiki-history.controller.coffee
###
taiga = @.taiga
module = angular.module("taigaWikiHistory")
class WikiHistoryController
@.$inject = [
"tgWikiHistoryService"
]
constructor: (@wikiHistoryService) ->
taiga.defineImmutableProperty @, 'historyEntries', () => return @wikiHistoryService.historyEntries
initializeHistoryEntries: (wikiId) ->
if wikiId
@wikiHistoryService.setWikiId(wikiId)
@wikiHistoryService.loadHistoryEntries()
module.controller("WikiHistoryCtrl", WikiHistoryController)

View File

@ -0,0 +1,62 @@
###
# Copyright (C) 2014-2015 Taiga Agile LLC <taiga@taiga.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: wiki-history.controller.spec.coffee
###
describe "WikiHistorySection", ->
provide = null
controller = null
mocks = {}
_mockTgWikiHistoryService = () ->
mocks.tgWikiHistoryService = {
setWikiId: sinon.stub(),
loadHistoryEntries: sinon.stub()
}
provide.value "tgWikiHistoryService", mocks.tgWikiHistoryService
_mocks = () ->
module ($provide) ->
provide = $provide
_mockTgWikiHistoryService()
return null
beforeEach ->
module "taigaWikiHistory"
_mocks()
inject ($controller) ->
controller = $controller
it "initialize histori entries with id", ->
wikiId = 42
historyCtrl = controller "WikiHistoryCtrl"
historyCtrl.initializeHistoryEntries(wikiId)
expect(mocks.tgWikiHistoryService.setWikiId).to.be.calledOnce
expect(mocks.tgWikiHistoryService.setWikiId).to.be.calledWith(wikiId)
expect(mocks.tgWikiHistoryService.loadHistoryEntries).to.be.calledOnce
it "initialize history entries without id", ->
historyCtrl = controller "WikiHistoryCtrl"
historyCtrl.initializeHistoryEntries()
expect(mocks.tgWikiHistoryService.setWikiId).to.not.be.calledOnce
expect(mocks.tgWikiHistoryService.loadHistoryEntries).to.be.calledOnce

View File

@ -0,0 +1,41 @@
###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: wiki-history.directive.coffee
###
bindOnce = @.taiga.bindOnce
module = angular.module('taigaWikiHistory')
WikiHistoryDirective = () ->
link = (scope, el, attrs, ctrl) ->
bindOnce scope, 'vm.wikiId', (value) ->
ctrl.initializeHistoryEntries(value)
return {
scope: {},
bindToController: {
wikiId: "<"
}
controller: "WikiHistoryCtrl",
controllerAs: "vm",
templateUrl:"wiki/history/wiki-history.html",
link: link
}
module.directive("tgWikiHistory", WikiHistoryDirective)

View File

@ -0,0 +1,12 @@
nav.history-tabs(ng-if="vm.historyEntries")
a.history-tab.active(
href=""
title="{{ACTIVITY.TITLE}}"
translate="ACTIVITY.TITLE"
)
section.wiki-history(ng-if="vm.historyEntries")
tg-wiki-history-entry.wiki-history-entry(
tg-repeat="historyEntry in vm.historyEntries"
history-entry="historyEntry"
)

View File

@ -0,0 +1,20 @@
###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: wiki-history.module.coffee
###
angular.module("taigaWikiHistory", [])

View File

@ -0,0 +1,3 @@
.wiki-history {
margin-bottom: 2rem;
}

View File

@ -0,0 +1,51 @@
###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: wiki-history.service.coffee
###
taiga = @.taiga
module = angular.module('taigaWikiHistory')
class WikiHistoryService extends taiga.Service
@.$inject = [
"tgResources"
"tgXhrErrorService"
]
constructor: (@rs, @xhrError) ->
@._wikiId = null
@._historyEntries = Immutable.List()
taiga.defineImmutableProperty @, "wikiId", () => return @._wikiId
taiga.defineImmutableProperty @, "historyEntries", () => return @._historyEntries
setWikiId: (wikiId) ->
@._wikiId = wikiId
@._historyEntries = Immutable.List()
loadHistoryEntries: () ->
return if not @._wikiId
return @rs.wikiHistory.getWikiHistory(@._wikiId)
.then (historyEntries) =>
if historyEntries.size
@._historyEntries = historyEntries.reverse()
.catch (xhr) =>
@xhrError.response(xhr)
_
module.service("tgWikiHistoryService", WikiHistoryService)

View File

@ -0,0 +1,92 @@
###
# Copyright (C) 2014-2015 Taiga Agile LLC <taiga@taiga.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: wiki-history.service.spec.coffee
###
describe "tgWikiHistoryService", ->
$provide = null
wikiHistoryService = null
mocks = {}
_mockTgResources = () ->
mocks.tgResources = {
wikiHistory: {
getWikiHistory: sinon.stub()
}
}
$provide.value("tgResources", mocks.tgResources)
_mockXhrErrorService = () ->
mocks.xhrErrorService = {
response: sinon.stub()
}
$provide.value "tgXhrErrorService", mocks.xhrErrorService
_mocks = ->
module (_$provide_) ->
$provide = _$provide_
_mockTgResources()
_mockXhrErrorService()
return null
_inject = ->
inject (_tgWikiHistoryService_) ->
wikiHistoryService = _tgWikiHistoryService_
_setup = ->
_mocks()
_inject()
beforeEach ->
module "taigaWikiHistory"
_setup()
it "populate history entries", (done) ->
wikiId = 42
historyEntries = Immutable.List([
{id: 1, name: 'history entrie 1'},
{id: 2, name: 'history entrie 2'},
{id: 3, name: 'history entrie 3'},
])
mocks.tgResources.wikiHistory.getWikiHistory.withArgs(wikiId).promise().resolve(historyEntries)
wikiHistoryService.setWikiId(wikiId)
expect(wikiHistoryService.wikiId).to.be.equal(wikiId)
expect(wikiHistoryService.historyEntries.size).to.be.equal(0)
wikiHistoryService.loadHistoryEntries().then () ->
expect(wikiHistoryService.historyEntries.size).to.be.equal(3)
done()
it "reset history entries if wikiId change", () ->
wikiId = 42
wikiHistoryService._historyEntries = Immutable.List([
{id: 1, name: 'history entrie 1'},
{id: 2, name: 'history entrie 2'},
{id: 3, name: 'history entrie 3'},
])
expect(wikiHistoryService.historyEntries.size).to.be.equal(3)
wikiHistoryService.setWikiId(wikiId)
expect(wikiHistoryService.historyEntries.size).to.be.equal(0)

View File

@ -12,3 +12,12 @@
.wiki-times-edited .wiki-times-edited
span.number <%- totalEditions %> span.number <%- totalEditions %>
span.description(translate="WIKI.SUMMARY.TIMES_EDITED") span.description(translate="WIKI.SUMMARY.TIMES_EDITED")
tg-svg.remove(
tg-check-permission="delete_wiki_page"
title="{{'WIKI.REMOVE' | translate}}"
ng-click="ctrl.delete()"
svg-icon="icon-trash"
ng-if="wiki.id"
)

View File

@ -16,7 +16,6 @@ div.wrapper(
span(tg-bo-bind="project.name") span(tg-bo-bind="project.name")
span.green(translate="PROJECT.SECTION.WIKI") span.green(translate="PROJECT.SECTION.WIKI")
h2.wiki-title(ng-bind='wikiTitle') h2.wiki-title(ng-bind='wikiTitle')
section.wiki-content( section.wiki-content(
tg-editable-wysiwyg, tg-editable-wysiwyg,
@ -24,7 +23,7 @@ div.wrapper(
ng-model="wiki" ng-model="wiki"
) )
div.summary.wiki-summary( .summary.wiki-summary(
tg-wiki-summary tg-wiki-summary
ng-model="wiki" ng-model="wiki"
ng-if="wiki.id" ng-if="wiki.id"
@ -38,12 +37,7 @@ div.wrapper(
edit-permission = "modify_wiki_page" edit-permission = "modify_wiki_page"
) )
a.remove( tg-wiki-history(
href=""
ng-click="ctrl.delete()"
ng-if="wiki.id" ng-if="wiki.id"
title="{{'WIKI.REMOVE' | translate}}" wiki-id="wiki.id"
tg-check-permission="delete_wiki_page"
) )
tg-svg(svg-icon="icon-trash")
span(translate="WIKI.REMOVE")

View File

@ -0,0 +1,32 @@
.history-tabs {
background: $whitish;
display: flex;
flex-direction: row;
a {
display: inline-block;
padding: .75rem 1rem;
&:hover {
color: $primary;
}
}
.history-tab {
@include font-type(bold);
border-bottom: 3px solid transparent;
color: $gray-light;
transition: all .1s linear;
&.active {
border-bottom: 3px solid $grayer;
color: $grayer;
}
}
.order-comments {
@include font-type(light);
color: $grayer;
margin-left: auto;
transition: none;
}
.icon-arrow-up,
.icon-arrow-down {
@include svg-size(.75rem);
}
}

View File

@ -1,4 +1,5 @@
.wiki { .wiki {
max-width: 1024px;
.wysiwyg { .wysiwyg {
margin-bottom: 0; margin-bottom: 0;
} }
@ -8,28 +9,10 @@
margin-bottom: 0; margin-bottom: 0;
padding: 1rem; padding: 1rem;
} }
.remove {
@include font-size(small);
color: $gray-light;
cursor: pointer;
&:hover {
color: $red-light;
transition: color .1s linear;
.icon {
fill: $red-light;
transition: fill .1s linear;
}
}
.icon {
color: $gray-light;
margin-right: .2rem;
}
}
} }
.wiki-content { .wiki-content {
@include font-size(large); @include font-size(large);
max-width: 1024px;
position: relative; position: relative;
&.editable { &.editable {
&:hover { &:hover {

View File

@ -27,4 +27,16 @@
@include font-size(large); @include font-size(large);
white-space: nowrap; white-space: nowrap;
} }
.remove {
fill: $gray-light;
margin-left: auto;
transition: fill .1s linear;
&:hover {
cursor: pointer;
fill: $red-light;
}
svg {
@include svg-size(1.5rem);
}
}
} }