@ebiz/designer-components 0.0.50 → 0.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/designer-components.css +1 -1
- package/dist/index.mjs +587 -554
- package/package.json +2 -1
- package/src/components/EbizApproval.vue +13 -3
- package/src/components/EbizDiv.vue +33 -0
- package/src/components/EbizEmployeeSelector.vue +2 -2
- package/src/components/EbizVxeTable.vue +291 -0
- package/src/index.js +4 -1
- package/src/router/index.js +12 -1
- package/src/views/Home.vue +7 -1
- package/src/views/PermissionBoxDemo.vue +86 -0
- package/src/views/VxeTableDemo.vue +280 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ebiz/designer-components",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.52",
|
4
4
|
"private": false,
|
5
5
|
"publishConfig": {
|
6
6
|
"access": "public"
|
@@ -19,6 +19,7 @@
|
|
19
19
|
"dependencies": {
|
20
20
|
"axios": "^1.8.1",
|
21
21
|
"echarts": "^5.6.0",
|
22
|
+
"vxe-table": "^4.13.31",
|
22
23
|
"tdesign-vue-next": "^1.12.0",
|
23
24
|
"unplugin-auto-import": "^19.0.0",
|
24
25
|
"unplugin-vue-components": "^28.0.0",
|
@@ -122,6 +122,13 @@ const fetchHistory = () => {
|
|
122
122
|
}, {}, '/tasks/process/detail').then(res=>{
|
123
123
|
selectedApprover.value = res?.variables?.form?.approverList ?? [];
|
124
124
|
selectedCC.value = res?.variables?.form?.ccList ?? [];
|
125
|
+
if(!selectedApprover.value.length){
|
126
|
+
dataService.fetch({
|
127
|
+
apiKey: "test_app_11111"
|
128
|
+
}, {},"/appdata/process?key=test_app_11111").then(res=>{
|
129
|
+
selectedApprover.value = res?.data?.at(0)?.approve_list || [];
|
130
|
+
})
|
131
|
+
}
|
125
132
|
})
|
126
133
|
}
|
127
134
|
|
@@ -184,6 +191,11 @@ const fetchEmployeeList = async () => {
|
|
184
191
|
'/process/userList'
|
185
192
|
)
|
186
193
|
employeeList.value = response || [];
|
194
|
+
dataService.fetch({
|
195
|
+
apiKey: "test_app_11111"
|
196
|
+
}, {},"/appdata/execute/plugin?key=test_app_11111").then(res=>{
|
197
|
+
console.log(res,190)
|
198
|
+
})
|
187
199
|
if(props.id) {
|
188
200
|
fetchHistory();
|
189
201
|
}
|
@@ -236,13 +248,11 @@ const handleAddCC = () => {
|
|
236
248
|
showCCSelector.value = true
|
237
249
|
}
|
238
250
|
|
239
|
-
// 初始化时获取员工列表
|
240
|
-
fetchEmployeeList()
|
241
251
|
|
242
252
|
// 监听查询条件变化
|
243
253
|
watch([() => props.type, () => props.value, () => props.showRootOrg, () => props.childDeptEnable], () => {
|
244
254
|
fetchEmployeeList()
|
245
|
-
})
|
255
|
+
}, { immediate: true })
|
246
256
|
</script>
|
247
257
|
|
248
258
|
<style lang="less" scoped>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<script setup>
|
2
|
+
import { ref, watch } from 'vue';
|
3
|
+
|
4
|
+
const props = defineProps({
|
5
|
+
key: {
|
6
|
+
type: String,
|
7
|
+
required: true,
|
8
|
+
default: ''
|
9
|
+
}
|
10
|
+
});
|
11
|
+
|
12
|
+
const isShow = ref(true);
|
13
|
+
|
14
|
+
const checkPermission = () => {
|
15
|
+
try {
|
16
|
+
const permissionKeysStr = localStorage.getItem('permissionKeys') || '[]';
|
17
|
+
const permissionKeys = JSON.parse(permissionKeysStr);
|
18
|
+
const hasPermission = permissionKeys.includes(props.key);
|
19
|
+
isShow.value = hasPermission;
|
20
|
+
} catch (error) {
|
21
|
+
console.error('解析权限数据失败:', error);
|
22
|
+
isShow.value = false;
|
23
|
+
}
|
24
|
+
};
|
25
|
+
|
26
|
+
watch(() => props.key, checkPermission, { immediate: true });
|
27
|
+
</script>
|
28
|
+
|
29
|
+
<template>
|
30
|
+
<div v-if="isShow">
|
31
|
+
<slot></slot>
|
32
|
+
</div>
|
33
|
+
</template>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
<!-- 选择弹窗 -->
|
20
20
|
<t-dialog v-model:visible="dialogVisible" header="选择人员" :width="800" footer :close-btn="true"
|
21
|
-
:close-on-esc-keydown="true" :close-on-overlay-click="true">
|
21
|
+
:close-on-esc-keydown="true" :close-on-overlay-click="true" destroyOnClose>
|
22
22
|
|
23
23
|
<!-- 选项卡 -->
|
24
24
|
<t-tabs v-model="activeTab" class="selector-tabs">
|
@@ -200,7 +200,7 @@ const props = defineProps({
|
|
200
200
|
},
|
201
201
|
visible:{
|
202
202
|
type: Boolean,
|
203
|
-
default:
|
203
|
+
default: false
|
204
204
|
},
|
205
205
|
// 是否包含部门
|
206
206
|
includeDepartment: {
|
@@ -0,0 +1,291 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="ebiz-vxe-table-container">
|
3
|
+
<vxe-table
|
4
|
+
ref="vxeTableRef"
|
5
|
+
v-bind="tableProp"
|
6
|
+
v-on="tableEvents"
|
7
|
+
:data="tableData"
|
8
|
+
>
|
9
|
+
<template v-for="(col, index) in renderColumns" :key="index">
|
10
|
+
<!-- 处理列分组 -->
|
11
|
+
<template v-if="col.childTableCols && col.childTableCols.length">
|
12
|
+
<vxe-colgroup :title="col.title">
|
13
|
+
<vxe-column
|
14
|
+
v-for="(childCol, childIndex) in col.childTableCols"
|
15
|
+
:key="childIndex"
|
16
|
+
:field="childCol.field"
|
17
|
+
:title="childCol.title"
|
18
|
+
:width="childCol.width"
|
19
|
+
:min-width="childCol.minWidth"
|
20
|
+
:sortable="childCol.sortable"
|
21
|
+
:filters="childCol.filters"
|
22
|
+
:tree-node="childCol.treeNode"
|
23
|
+
:align="childCol.align || 'left'"
|
24
|
+
:show-overflow="childCol.showOverflow !== false"
|
25
|
+
>
|
26
|
+
<!-- 处理自定义渲染 -->
|
27
|
+
<template v-if="childCol.type === 'jsx'" #default="scope">
|
28
|
+
<component :is="childCol.render" :scope="scope" />
|
29
|
+
</template>
|
30
|
+
<template v-else-if="childCol.type === 'slot'" #default="scope">
|
31
|
+
<slot :name="childCol.slotName" :scope="scope"></slot>
|
32
|
+
</template>
|
33
|
+
</vxe-column>
|
34
|
+
</vxe-colgroup>
|
35
|
+
</template>
|
36
|
+
<!-- 普通列 -->
|
37
|
+
<template v-else>
|
38
|
+
<vxe-column
|
39
|
+
:field="col.field"
|
40
|
+
:title="col.title"
|
41
|
+
:width="col.width"
|
42
|
+
:min-width="col.minWidth"
|
43
|
+
:type="getColumnType(col)"
|
44
|
+
:sortable="col.sortable"
|
45
|
+
:filters="col.filters"
|
46
|
+
:tree-node="col.treeNode"
|
47
|
+
:align="col.align || 'left'"
|
48
|
+
:show-overflow="col.showOverflow !== false"
|
49
|
+
>
|
50
|
+
<!-- 处理自定义渲染 -->
|
51
|
+
<template v-if="col.type === 'jsx'" #default="scope">
|
52
|
+
<component :is="col.render" :scope="scope" />
|
53
|
+
</template>
|
54
|
+
<template v-else-if="col.type === 'slot'" #default="scope">
|
55
|
+
<slot :name="col.slotName" :scope="scope"></slot>
|
56
|
+
</template>
|
57
|
+
</vxe-column>
|
58
|
+
</template>
|
59
|
+
</template>
|
60
|
+
|
61
|
+
<!-- 表格空数据模板 -->
|
62
|
+
<template #empty>
|
63
|
+
<div class="vxe-table-empty">
|
64
|
+
<slot name="empty">
|
65
|
+
<span>{{ emptyText }}</span>
|
66
|
+
</slot>
|
67
|
+
</div>
|
68
|
+
</template>
|
69
|
+
</vxe-table>
|
70
|
+
|
71
|
+
<!-- 分页组件 -->
|
72
|
+
<vxe-pager
|
73
|
+
v-if="isPagination"
|
74
|
+
v-bind="pagerConfig"
|
75
|
+
v-on="pagerEvents"
|
76
|
+
:current-page="currentPage"
|
77
|
+
:page-size="pageSize"
|
78
|
+
:total="total"
|
79
|
+
:layouts="pagerLayouts"
|
80
|
+
@page-change="handlePageChange"
|
81
|
+
/>
|
82
|
+
</div>
|
83
|
+
</template>
|
84
|
+
|
85
|
+
<script setup>
|
86
|
+
import { ref, computed, onMounted, nextTick } from 'vue';
|
87
|
+
import VXETable from 'vxe-table';
|
88
|
+
|
89
|
+
// 定义组件的props
|
90
|
+
const props = defineProps({
|
91
|
+
// 表格数据
|
92
|
+
tableData: {
|
93
|
+
type: Array,
|
94
|
+
default: () => []
|
95
|
+
},
|
96
|
+
// 表格列配置
|
97
|
+
tableCols: {
|
98
|
+
type: Array,
|
99
|
+
default: () => []
|
100
|
+
},
|
101
|
+
// 表格属性配置
|
102
|
+
tableProp: {
|
103
|
+
type: Object,
|
104
|
+
default: () => ({
|
105
|
+
'auto-resize': true,
|
106
|
+
border: true,
|
107
|
+
'row-id': 'id',
|
108
|
+
'highlight-current-row': true,
|
109
|
+
'show-overflow': true,
|
110
|
+
'tree-config': { children: 'children' }
|
111
|
+
})
|
112
|
+
},
|
113
|
+
// 表格事件配置
|
114
|
+
tableEvents: {
|
115
|
+
type: Object,
|
116
|
+
default: () => ({})
|
117
|
+
},
|
118
|
+
// 分页组件配置
|
119
|
+
pagerConfig: {
|
120
|
+
type: Object,
|
121
|
+
default: () => ({})
|
122
|
+
},
|
123
|
+
// 分页事件
|
124
|
+
pagerEvents: {
|
125
|
+
type: Object,
|
126
|
+
default: () => ({})
|
127
|
+
},
|
128
|
+
// 是否显示分页
|
129
|
+
isPagination: {
|
130
|
+
type: Boolean,
|
131
|
+
default: true
|
132
|
+
},
|
133
|
+
// 当前页码
|
134
|
+
currentPage: {
|
135
|
+
type: Number,
|
136
|
+
default: 1
|
137
|
+
},
|
138
|
+
// 每页条数
|
139
|
+
pageSize: {
|
140
|
+
type: Number,
|
141
|
+
default: 10
|
142
|
+
},
|
143
|
+
// 数据总条数
|
144
|
+
total: {
|
145
|
+
type: Number,
|
146
|
+
default: 0
|
147
|
+
},
|
148
|
+
// 空数据提示文本
|
149
|
+
emptyText: {
|
150
|
+
type: String,
|
151
|
+
default: '暂无数据'
|
152
|
+
}
|
153
|
+
});
|
154
|
+
|
155
|
+
// 定义emit事件
|
156
|
+
const emit = defineEmits([
|
157
|
+
'query',
|
158
|
+
'update:currentPage',
|
159
|
+
'update:pageSize',
|
160
|
+
'page-change',
|
161
|
+
'size-change'
|
162
|
+
]);
|
163
|
+
|
164
|
+
// 表格实例引用
|
165
|
+
const vxeTableRef = ref(null);
|
166
|
+
|
167
|
+
// 处理表格列,添加唯一ID
|
168
|
+
const renderColumns = computed(() => {
|
169
|
+
return props.tableCols.map(col => {
|
170
|
+
// 创建新的列对象并添加唯一ID
|
171
|
+
const newCol = { ...col, id: 1 };
|
172
|
+
|
173
|
+
// 处理子列配置
|
174
|
+
if (newCol.childTableCols && newCol.childTableCols.length) {
|
175
|
+
newCol.childTableCols = newCol.childTableCols.map(childCol => {
|
176
|
+
return { ...childCol, id: 1 };
|
177
|
+
});
|
178
|
+
}
|
179
|
+
|
180
|
+
return newCol;
|
181
|
+
});
|
182
|
+
});
|
183
|
+
|
184
|
+
// 分页布局配置
|
185
|
+
const pagerLayouts = computed(() => {
|
186
|
+
return ['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total'];
|
187
|
+
});
|
188
|
+
|
189
|
+
// 获取列类型
|
190
|
+
const getColumnType = (col) => {
|
191
|
+
// vxe-table内置类型:checkbox、radio、expand、seq
|
192
|
+
if (['checkbox', 'radio', 'expand', 'seq'].includes(col.type)) {
|
193
|
+
return col.type;
|
194
|
+
}
|
195
|
+
return null;
|
196
|
+
};
|
197
|
+
|
198
|
+
// 表格查询方法
|
199
|
+
const query = (page = props.currentPage, size = props.pageSize) => {
|
200
|
+
emit('query', page, size);
|
201
|
+
};
|
202
|
+
|
203
|
+
// 初始化表格
|
204
|
+
onMounted(() => {
|
205
|
+
// 如果配置了自动查询,则在组件挂载后自动查询数据
|
206
|
+
if (props.tableProp['enable-auto-query'] !== false) {
|
207
|
+
nextTick(() => {
|
208
|
+
query();
|
209
|
+
});
|
210
|
+
}
|
211
|
+
});
|
212
|
+
|
213
|
+
// 处理分页变化
|
214
|
+
const handlePageChange = ({ currentPage, pageSize }) => {
|
215
|
+
emit('update:currentPage', currentPage);
|
216
|
+
emit('update:pageSize', pageSize);
|
217
|
+
emit('page-change', { currentPage, pageSize });
|
218
|
+
query(currentPage, pageSize);
|
219
|
+
};
|
220
|
+
|
221
|
+
// 暴露表格实例方法
|
222
|
+
const getInstance = () => {
|
223
|
+
return vxeTableRef.value;
|
224
|
+
};
|
225
|
+
|
226
|
+
// 完成加载,设置表格数据
|
227
|
+
const complete = (data, totalCount) => {
|
228
|
+
if (data === false) {
|
229
|
+
// 加载失败
|
230
|
+
VXETable.modal.message({ content: '加载失败', status: 'error' });
|
231
|
+
return;
|
232
|
+
}
|
233
|
+
|
234
|
+
if (totalCount !== undefined) {
|
235
|
+
// 更新总数
|
236
|
+
emit('update:total', totalCount);
|
237
|
+
}
|
238
|
+
};
|
239
|
+
|
240
|
+
// 获取选中行
|
241
|
+
const getSelectedRows = () => {
|
242
|
+
if (vxeTableRef.value) {
|
243
|
+
return vxeTableRef.value.getCheckboxRecords();
|
244
|
+
}
|
245
|
+
return [];
|
246
|
+
};
|
247
|
+
|
248
|
+
// 导出表格数据
|
249
|
+
const exportData = (options = {}) => {
|
250
|
+
if (vxeTableRef.value) {
|
251
|
+
return vxeTableRef.value.exportData(options);
|
252
|
+
}
|
253
|
+
};
|
254
|
+
|
255
|
+
// 重新加载表格数据
|
256
|
+
const reloadData = (data = null) => {
|
257
|
+
if (vxeTableRef.value) {
|
258
|
+
if (data) {
|
259
|
+
return vxeTableRef.value.loadData(data);
|
260
|
+
} else {
|
261
|
+
return vxeTableRef.value.loadData(props.tableData);
|
262
|
+
}
|
263
|
+
}
|
264
|
+
};
|
265
|
+
|
266
|
+
// 将内部方法暴露给父组件
|
267
|
+
defineExpose({
|
268
|
+
query,
|
269
|
+
complete,
|
270
|
+
getSelectedRows,
|
271
|
+
exportData,
|
272
|
+
getInstance,
|
273
|
+
reloadData
|
274
|
+
});
|
275
|
+
</script>
|
276
|
+
|
277
|
+
<style scoped>
|
278
|
+
.ebiz-vxe-table-container {
|
279
|
+
width: 100%;
|
280
|
+
height: 100%;
|
281
|
+
display: flex;
|
282
|
+
flex-direction: column;
|
283
|
+
}
|
284
|
+
|
285
|
+
.vxe-table-empty {
|
286
|
+
padding: 30px 0;
|
287
|
+
text-align: center;
|
288
|
+
color: #909399;
|
289
|
+
font-size: 14px;
|
290
|
+
}
|
291
|
+
</style>
|
package/src/index.js
CHANGED
@@ -63,6 +63,7 @@ import EbizDepartmentSelector from './components/EbizDepartmentSelector.vue';
|
|
63
63
|
import EbizTdesignButtonDialog from './components/EbizTdesignButtonDialog.vue';
|
64
64
|
import { MessagePlugin as EbizMessage } from 'tdesign-vue-next';
|
65
65
|
import EbizApproval from './components/EbizApproval.vue';
|
66
|
+
import EbizDiv from './components/EbizDiv.vue';
|
66
67
|
|
67
68
|
// import EbizDescriptions from './components/EbizDescriptions.vue';
|
68
69
|
// import EbizDescriptionsItem from './components/EbizDescriptionsItem.vue'
|
@@ -90,6 +91,7 @@ import EbizSForm from './components/senior/EbizSForm/index.vue';
|
|
90
91
|
import EbizSFormItem from './components/senior/EbizSForm/item.vue';
|
91
92
|
import EbizSDialog from "./components/senior/EbizSDialog/index.vue";
|
92
93
|
|
94
|
+
|
93
95
|
// 导出组件
|
94
96
|
export {
|
95
97
|
MyComponent,
|
@@ -211,5 +213,6 @@ export {
|
|
211
213
|
EbizSFormItem,
|
212
214
|
EbizSDialog,
|
213
215
|
// 新增 EbizApproval 组件
|
214
|
-
EbizApproval
|
216
|
+
EbizApproval,
|
217
|
+
EbizDiv
|
215
218
|
};
|
package/src/router/index.js
CHANGED
@@ -4,7 +4,6 @@ import ButtonView from '../views/Button.vue'
|
|
4
4
|
import TableView from '../views/TableView.vue'
|
5
5
|
import TdesignDescriptions from '../views/TdesignDescriptions.vue'
|
6
6
|
import EbizSForm from '../views/EbizSForm/index.vue'
|
7
|
-
import path from 'path'
|
8
7
|
|
9
8
|
const routes = [
|
10
9
|
{
|
@@ -353,6 +352,18 @@ const routes = [
|
|
353
352
|
name:"EbizApproval",
|
354
353
|
component:()=>import('../views/EbizApprovalDemo.vue'),
|
355
354
|
meta:{title:"Ebiz审批组件示例"}
|
355
|
+
},
|
356
|
+
{
|
357
|
+
path:"/vxe-table",
|
358
|
+
name:"EbizVxeTable",
|
359
|
+
component:()=>import('../views/VxeTableDemo.vue'),
|
360
|
+
meta:{title:"EbizVxeTable组件示例"}
|
361
|
+
},
|
362
|
+
{
|
363
|
+
path: '/permission-box',
|
364
|
+
name: 'PermissionBox',
|
365
|
+
component: () => import('../views/PermissionBoxDemo.vue'),
|
366
|
+
meta: { title: 'Ebiz权限盒子组件示例' }
|
356
367
|
}
|
357
368
|
]
|
358
369
|
|
package/src/views/Home.vue
CHANGED
@@ -22,6 +22,11 @@
|
|
22
22
|
<div class="component-title">树形合并表格</div>
|
23
23
|
<div class="component-desc">支持树形展示和单元格合并的表格组件</div>
|
24
24
|
</router-link>
|
25
|
+
|
26
|
+
<router-link to="/permission-box" class="component-item">
|
27
|
+
<div class="component-title">权限盒子组件示例</div>
|
28
|
+
<div class="component-desc">用于展示权限控制的组件示例</div>
|
29
|
+
</router-link>
|
25
30
|
</div>
|
26
31
|
</div>
|
27
32
|
</template>
|
@@ -86,7 +91,8 @@ export default {
|
|
86
91
|
{ path: '/ebiz-map', title: '地图经纬度选择器组件示例' },
|
87
92
|
{ path: '/ebiz-s-data', title: 'Ebiz数据组件示例' },
|
88
93
|
{ path: '/ebiz-s-dialog', title: 'Ebiz高级弹窗组件示例' },
|
89
|
-
{ path: '/approval', title: 'Ebiz审批组件示例' }
|
94
|
+
{ path: '/approval', title: 'Ebiz审批组件示例' },
|
95
|
+
{ path: '/vxe-table', title: 'EbizVxeTable示例' }
|
90
96
|
]
|
91
97
|
|
92
98
|
return {
|
@@ -0,0 +1,86 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="permission-box-demo">
|
3
|
+
<h2>权限盒子组件演示</h2>
|
4
|
+
|
5
|
+
<div class="demo-section">
|
6
|
+
<h3>基础用法</h3>
|
7
|
+
<div class="demo-block">
|
8
|
+
<EbizDiv key="admin">
|
9
|
+
<div class="demo-content">
|
10
|
+
这是只有管理员可见的内容
|
11
|
+
</div>
|
12
|
+
</EbizDiv>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div class="demo-section">
|
17
|
+
<h3>权限控制演示</h3>
|
18
|
+
<div class="demo-block">
|
19
|
+
<t-space direction="vertical">
|
20
|
+
<t-button @click="setPermission(['admin'])">设置管理员权限</t-button>
|
21
|
+
<t-button @click="setPermission(['user'])">设置普通用户权限</t-button>
|
22
|
+
<t-button @click="setPermission([])">清除所有权限</t-button>
|
23
|
+
</t-space>
|
24
|
+
|
25
|
+
<div class="permission-examples">
|
26
|
+
<EbizDiv key="admin">
|
27
|
+
<t-alert theme="success" message="管理员可见内容" />
|
28
|
+
</EbizDiv>
|
29
|
+
|
30
|
+
<EbizDiv key="user">
|
31
|
+
<t-alert theme="info" message="普通用户可见内容" />
|
32
|
+
</EbizDiv>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
</template>
|
38
|
+
|
39
|
+
<script setup>
|
40
|
+
import { EbizDiv } from '../index.js';
|
41
|
+
import { Button as TButton, Space as TSpace, Alert as TAlert } from 'tdesign-vue-next';
|
42
|
+
|
43
|
+
const setPermission = (permissions) => {
|
44
|
+
localStorage.setItem('permissionKeys', JSON.stringify(permissions));
|
45
|
+
// 刷新页面以重新加载权限
|
46
|
+
window.location.reload();
|
47
|
+
};
|
48
|
+
</script>
|
49
|
+
|
50
|
+
<style scoped>
|
51
|
+
.permission-box-demo {
|
52
|
+
padding: 20px;
|
53
|
+
}
|
54
|
+
|
55
|
+
.demo-section {
|
56
|
+
margin-bottom: 30px;
|
57
|
+
}
|
58
|
+
|
59
|
+
h2 {
|
60
|
+
margin-bottom: 20px;
|
61
|
+
}
|
62
|
+
|
63
|
+
h3 {
|
64
|
+
margin-bottom: 15px;
|
65
|
+
}
|
66
|
+
|
67
|
+
.demo-block {
|
68
|
+
padding: 20px;
|
69
|
+
border: 1px solid #eee;
|
70
|
+
border-radius: 4px;
|
71
|
+
}
|
72
|
+
|
73
|
+
.demo-content {
|
74
|
+
padding: 16px;
|
75
|
+
background-color: #f5f5f5;
|
76
|
+
border-radius: 4px;
|
77
|
+
}
|
78
|
+
|
79
|
+
.permission-examples {
|
80
|
+
margin-top: 20px;
|
81
|
+
}
|
82
|
+
|
83
|
+
.permission-examples > * {
|
84
|
+
margin-bottom: 10px;
|
85
|
+
}
|
86
|
+
</style>
|