Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
16
Merge Requests
16
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
slapos.core
Commits
edef233e
Commit
edef233e
authored
Oct 02, 2024
by
Romain Courteaud
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
slapos_panel: action to change a Subscription price
parent
c1b7e30f
Pipeline
#37252
passed with stage
in 0 seconds
Changes
10
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1215 additions
and
0 deletions
+1215
-0
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSCodingStyle.py
...Item/portal_components/test.erp5.testSlapOSCodingStyle.py
+1
-0
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSERP5SubscriptionScenario.py
...omponents/test.erp5.testSlapOSERP5SubscriptionScenario.py
+326
-0
master/bt5/slapos_panel/ActionTemplateItem/portal_types/Subscription%20Request/change_slapos_submitted_price.xml
.../Subscription%20Request/change_slapos_submitted_price.xml
+96
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeFromPayableToFree.py
...apos_panel/SubscriptionRequest_changeFromPayableToFree.py
+116
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeFromPayableToFree.xml
...pos_panel/SubscriptionRequest_changeFromPayableToFree.xml
+62
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeSlaposSubmittedPrice.py
...s_panel/SubscriptionRequest_changeSlaposSubmittedPrice.py
+75
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeSlaposSubmittedPrice.xml
..._panel/SubscriptionRequest_changeSlaposSubmittedPrice.xml
+62
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog.xml
...scriptionRequest_viewChangeSlaposSubmittedPriceDialog.xml
+160
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog/your_price.xml
...quest_viewChangeSlaposSubmittedPriceDialog/your_price.xml
+316
-0
master/bt5/slapos_panel/bt/template_action_path_list
master/bt5/slapos_panel/bt/template_action_path_list
+1
-0
No files found.
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSCodingStyle.py
View file @
edef233e
...
@@ -272,6 +272,7 @@ def makeTestSlapOSCodingStyleTestCase(tested_business_template):
...
@@ -272,6 +272,7 @@ def makeTestSlapOSCodingStyleTestCase(tested_business_template):
'slapos_panel/SoftwareInstance_getNewsDict'
,
'slapos_panel/SoftwareInstance_getNewsDict'
,
'slapos_panel/SoftwareProduct_addSlapOSSoftwareRelease'
,
'slapos_panel/SoftwareProduct_addSlapOSSoftwareRelease'
,
'slapos_panel/SoftwareProduct_addSlapOSSoftwareType'
,
'slapos_panel/SoftwareProduct_addSlapOSSoftwareType'
,
'slapos_panel/SubscriptionRequest_changeSlaposSubmittedPrice'
,
'slapos_panel/SubscriptionRequest_jumpToPaymentPage'
,
'slapos_panel/SubscriptionRequest_jumpToPaymentPage'
,
'slapos_panel/Ticket_addSlapOSEvent'
,
'slapos_panel/Ticket_addSlapOSEvent'
,
'slapos_panel/Ticket_closeSlapOS'
,
'slapos_panel/Ticket_closeSlapOS'
,
...
...
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSERP5SubscriptionScenario.py
View file @
edef233e
This diff is collapsed.
Click to expand it.
master/bt5/slapos_panel/ActionTemplateItem/portal_types/Subscription%20Request/change_slapos_submitted_price.xml
0 → 100644
View file @
edef233e
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ActionInformation"
module=
"Products.CMFCore.ActionInformation"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
action_type/object_jio_action
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
category
</string>
</key>
<value>
<string>
object_jio_action
</string>
</value>
</item>
<item>
<key>
<string>
condition
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
icon
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
change_slapos_submitted_price
</string>
</value>
</item>
<item>
<key>
<string>
permissions
</string>
</key>
<value>
<tuple>
<string>
View
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
priority
</string>
</key>
<value>
<float>
60.0
</float>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Change Submitted Price
</string>
</value>
</item>
<item>
<key>
<string>
visible
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Expression"
module=
"Products.CMFCore.Expression"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
text
</string>
</key>
<value>
<string>
string:${object_url}/SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"Expression"
module=
"Products.CMFCore.Expression"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
text
</string>
</key>
<value>
<string>
python: portal.Base_checkPermission(\'subscription_change_request_module\', \'Add portal content\') and (context.getSimulationState() == \'submitted\')
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeFromPayableToFree.py
0 → 100644
View file @
edef233e
portal
=
context
.
getPortalObject
()
Base_translateString
=
portal
.
Base_translateString
subscription_request
=
context
from
zExceptions
import
Unauthorized
if
REQUEST
is
not
None
:
raise
Unauthorized
batch
=
(
dialog_id
is
None
)
trade_condition_type
=
'manual'
if
activate_kw
is
None
:
activate_kw
=
{}
if
not
'tag'
in
activate_kw
:
activate_kw
[
'tag'
]
=
script
.
id
if
not
(
subscription_request
.
hasSourceSection
()
and
(
0
<
subscription_request
.
getPrice
(
0
))):
keep_items
=
{
'portal_status_level'
:
'warning'
,
'portal_status_message'
:
Base_translateString
(
'The Subscription Request is not a payable one'
)
}
if
batch
:
return
subscription_request
return
context
.
Base_renderForm
(
dialog_id
,
keep_items
=
keep_items
)
# Create the Subscription Change Request
item
=
subscription_request
.
getAggregateValue
()
if
item
.
getPortalType
()
==
'Project'
:
project
=
item
else
:
project
=
subscription_request
.
getSourceProjectValue
()
customer
=
subscription_request
.
getDestinationValue
()
try
:
subscription_change_request
=
subscription_request
.
getResourceValue
().
Resource_createSubscriptionRequest
(
customer
,
# [software_type, software_release],
subscription_request
.
getVariationCategoryList
(),
project
,
currency_value
=
subscription_request
.
getPriceCurrencyValue
(),
temp_object
=
True
,
item_value
=
item
,
causality_value
=
subscription_request
,
# XXX .getCausalityValue(),
portal_type
=
'Subscription Change Request'
,
trade_condition_type
=
trade_condition_type
)
except
AssertionError
:
current_trade_condition
=
None
else
:
current_trade_condition
=
subscription_change_request
.
getSpecialiseValue
()
new_sale_trade_condition
=
None
if
(
current_trade_condition
is
None
):
# Create a dedicated trade condition for the customer
# to define free price
previous_title
=
subscription_request
.
getTitle
()
specialise_trade_condition
=
subscription_request
.
getSpecialiseValue
()
while
(
specialise_trade_condition
.
hasSourceSection
())
or
(
specialise_trade_condition
.
hasDestination
()):
previous_title
=
specialise_trade_condition
.
getTitle
()
specialise_trade_condition
=
specialise_trade_condition
.
getSpecialiseValue
()
new_sale_trade_condition
=
portal
.
sale_trade_condition_module
.
newContent
(
portal_type
=
'Sale Trade Condition'
,
specialise_value
=
specialise_trade_condition
,
title
=
'%s for %s'
%
(
previous_title
,
customer
.
getTitle
()),
destination_value
=
customer
,
destination_section_value
=
customer
,
source_project
=
subscription_request
.
getSourceProject
(),
source
=
subscription_request
.
getSource
(),
price_currency
=
subscription_request
.
getPriceCurrency
(),
trade_condition_type
=
trade_condition_type
,
activate_kw
=
activate_kw
)
new_sale_trade_condition
.
validate
()
subscription_request
.
activate
(
after_tag
=
activate_kw
[
'tag'
]).
SubscriptionRequest_changeFromPayableToFree
(
None
)
keep_items
=
{
'portal_status_message'
:
Base_translateString
(
'Creating a free dedicated Trade Condition for the customer'
)
}
if
batch
:
return
new_sale_trade_condition
return
new_sale_trade_condition
.
Base_redirect
(
keep_items
=
keep_items
)
elif
(
current_trade_condition
.
getDestination
()
==
customer
.
getRelativeUrl
())
and
\
(
current_trade_condition
.
getSourceSection
(
None
)
is
None
):
# There is already a manual trade condition
# without any source section (free)
new_sale_trade_condition
=
current_trade_condition
subscription_change_request
=
subscription_request
.
getResourceValue
().
Resource_createSubscriptionRequest
(
customer
,
# [software_type, software_release],
subscription_request
.
getVariationCategoryList
(),
project
,
currency_value
=
subscription_request
.
getPriceCurrencyValue
(),
item_value
=
item
,
causality_value
=
subscription_request
,
portal_type
=
'Subscription Change Request'
,
trade_condition_type
=
trade_condition_type
)
keep_items
=
{
'portal_status_message'
:
Base_translateString
(
'Creating a Subscription Change Request'
)
}
if
batch
:
return
subscription_change_request
return
subscription_change_request
.
Base_redirect
(
keep_items
=
keep_items
)
else
:
keep_items
=
{
'portal_status_level'
:
'error'
,
'portal_status_message'
:
Base_translateString
(
'This customer already has an incompatible dedicated Trade Condition'
)
}
if
batch
:
raise
ValueError
(
keep_items
[
'portal_status_message'
])
return
current_trade_condition
.
Base_redirect
(
keep_items
=
keep_items
)
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeFromPayableToFree.xml
0 → 100644
View file @
edef233e
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"PythonScript"
module=
"Products.PythonScripts.PythonScript"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_container
</string>
</key>
<value>
<string>
container
</string>
</value>
</item>
<item>
<key>
<string>
name_context
</string>
</key>
<value>
<string>
context
</string>
</value>
</item>
<item>
<key>
<string>
name_m_self
</string>
</key>
<value>
<string>
script
</string>
</value>
</item>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string>
dialog_id, activate_kw=None, REQUEST=None, **kw
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SubscriptionRequest_changeFromPayableToFree
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeSlaposSubmittedPrice.py
0 → 100644
View file @
edef233e
from
DateTime
import
DateTime
portal
=
context
.
getPortalObject
()
Base_translateString
=
portal
.
Base_translateString
subscription_request
=
context
from
zExceptions
import
Unauthorized
if
REQUEST
is
not
None
:
raise
Unauthorized
batch
=
(
dialog_id
is
None
)
if
activate_kw
is
None
:
activate_kw
=
{}
tag
=
activate_kw
.
get
(
'tag'
,
script
.
id
)
activate_kw
[
'tag'
]
=
tag
######################################################
# Prevent some mistakes
if
subscription_request
.
getSimulationState
()
!=
'submitted'
:
keep_items
=
{
'portal_status_level'
:
'warning'
,
'portal_status_message'
:
Base_translateString
(
'Can only change submitted subscription request'
)
}
if
batch
:
raise
ValueError
(
keep_items
[
'portal_status_message'
])
return
subscription_request
.
Base_redirect
(
keep_items
=
keep_items
)
current_price
=
subscription_request
.
getPrice
()
if
not
current_price
:
keep_items
=
{
'portal_status_level'
:
'warning'
,
'portal_status_message'
:
Base_translateString
(
'Can not make a free subscription to a payable one'
)
}
if
batch
:
raise
ValueError
(
keep_items
[
'portal_status_message'
])
return
subscription_request
.
Base_redirect
(
keep_items
=
keep_items
)
######################################################
# From payable to free
if
not
price
:
return
subscription_request
.
SubscriptionRequest_changeFromPayableToFree
(
dialog_id
)
######################################################
# Change price
portal_type
=
'Subscription Change Request'
subscription_change_request
=
portal
.
getDefaultModule
(
portal_type
).
newContent
(
portal_type
=
portal_type
,
causality_value
=
subscription_request
,
start_date
=
DateTime
(),
price
=
price
,
# Copy all other properties
destination
=
subscription_request
.
getDestination
(),
destination_section
=
subscription_request
.
getDestinationSection
(),
destination_decision
=
subscription_request
.
getDestinationDecision
(),
destination_project
=
subscription_request
.
getDestinationProject
(),
resource
=
subscription_request
.
getResource
(),
aggregate
=
subscription_request
.
getAggregate
(),
variation_category_list
=
subscription_request
.
getVariationCategoryList
(),
quantity_unit
=
subscription_request
.
getQuantityUnit
(),
quantity
=
subscription_request
.
getQuantity
(),
ledger
=
subscription_request
.
getLedger
(),
source
=
subscription_request
.
getSource
(),
source_section
=
subscription_request
.
getSourceSection
(),
source_project
=
subscription_request
.
getSourceProject
(),
price_currency
=
subscription_request
.
getPriceCurrency
(),
specialise
=
subscription_request
.
getSpecialise
(),
)
subscription_change_request
.
submit
()
keep_items
=
{
'portal_status_message'
:
Base_translateString
(
'Subscription Change Request created'
)
}
if
batch
:
return
subscription_change_request
return
subscription_change_request
.
Base_redirect
(
keep_items
=
keep_items
)
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeSlaposSubmittedPrice.xml
0 → 100644
View file @
edef233e
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"PythonScript"
module=
"Products.PythonScripts.PythonScript"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_container
</string>
</key>
<value>
<string>
container
</string>
</value>
</item>
<item>
<key>
<string>
name_context
</string>
</key>
<value>
<string>
context
</string>
</value>
</item>
<item>
<key>
<string>
name_m_self
</string>
</key>
<value>
<string>
script
</string>
</value>
</item>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string>
price, dialog_id, activate_kw=None, REQUEST=None, **kw
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SubscriptionRequest_changeSlaposSubmittedPrice
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog.xml
0 → 100644
View file @
edef233e
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ERP5 Form"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_objects
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
SubscriptionRequest_changeSlaposSubmittedPrice
</string>
</value>
</item>
<item>
<key>
<string>
action_title
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
edit_order
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
enctype
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
group_list
</string>
</key>
<value>
<list>
<string>
left
</string>
<string>
right
</string>
<string>
center
</string>
<string>
bottom
</string>
<string>
hidden
</string>
</list>
</value>
</item>
<item>
<key>
<string>
groups
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
bottom
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
center
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
left
</string>
</key>
<value>
<list>
<string>
your_price
</string>
</list>
</value>
</item>
<item>
<key>
<string>
right
</string>
</key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog
</string>
</value>
</item>
<item>
<key>
<string>
method
</string>
</key>
<value>
<string>
POST
</string>
</value>
</item>
<item>
<key>
<string>
name
</string>
</key>
<value>
<string>
SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog
</string>
</value>
</item>
<item>
<key>
<string>
pt
</string>
</key>
<value>
<string>
form_dialog
</string>
</value>
</item>
<item>
<key>
<string>
row_length
</string>
</key>
<value>
<int>
4
</int>
</value>
</item>
<item>
<key>
<string>
stored_encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Change Submitted Price
</string>
</value>
</item>
<item>
<key>
<string>
unicode_mode
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
update_action
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
update_action_title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog/your_price.xml
0 → 100644
View file @
edef233e
This diff is collapsed.
Click to expand it.
master/bt5/slapos_panel/bt/template_action_path_list
View file @
edef233e
...
@@ -96,6 +96,7 @@ Software Product | slapos_panel_view
...
@@ -96,6 +96,7 @@ Software Product | slapos_panel_view
Software Release Module | slapos_panel_view
Software Release Module | slapos_panel_view
Software Release | slapos_panel_view
Software Release | slapos_panel_view
Subscription Request Module | slapos_panel_view
Subscription Request Module | slapos_panel_view
Subscription Request | change_slapos_submitted_price
Subscription Request | jump_pay_my_slapos_sale_invoice_transaction
Subscription Request | jump_pay_my_slapos_sale_invoice_transaction
Subscription Request | slapos_panel_view
Subscription Request | slapos_panel_view
Support Request Module | slapos_panel_view
Support Request Module | slapos_panel_view
...
...
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